;(self.webpackChunkmp_webgl = self.webpackChunkmp_webgl || []).push([
  [833],
  {
    1089: (e, t, i) => {
      'use strict'
      e.exports = i.p + 'images/scope.svg'
    },
    3220: (e, t, i) => {
      'use strict'
      e.exports = i.p + 'images/surface_grid_planar_256.png'
    },
    57721: (e, t, i) => {
      'use strict'
      e.exports = i.p + 'images/vert_arrows.png'
    },
    27273: (e, t, i) => {
      'use strict'
      e.exports = i.p + 'images/outlineBasic1024.png'
    },
    15278: (e, t, i) => {
      'use strict'
      e.exports = i.p + 'images/outlineBasic2048.png'
    },
    92787: (e, t, i) => {
      'use strict'
      e.exports = i.p + 'images/outlineBasic4096.png'
    },
    67929: (e, t, i) => {
      'use strict'
      e.exports = i.p + 'images/outlineBasic512.png'
    },
    53896: (e, t, i) => {
      'use strict'
      e.exports = i.p + 'images/outlineEnhanced1024.png'
    },
    38343: (e, t, i) => {
      'use strict'
      e.exports = i.p + 'images/outlineEnhanced2048.png'
    },
    73965: (e, t, i) => {
      'use strict'
      e.exports = i.p + 'images/outlineEnhanced4096.png'
    },
    33967: (e, t, i) => {
      'use strict'
      e.exports = i.p + 'images/outlineEnhanced512.png'
    },
    33757: (e, t, i) => {
      'use strict'
      e.exports = i.p + 'images/selected_sweep_glow.png'
    },
    58129: (e, t, i) => {
      'use strict'
      i.r(t), i.d(t, { default: () => WebVRLoader })
      var s = i(47724),
        n = i(40285),
        r = i(98828),
        o = i(66542),
        a = i(24930),
        h = i(88512),
        l = i(21479),
        d = i(36704),
        c = i(36822)
      const u = new h.Z('webvr-loader')
      class WebVRLoader extends s.Y {
        constructor() {
          super(...arguments), (this.name = 'webvr-loader')
        }
        async init(e, t) {
          ;(this.engine = t), (this.onExitVr = this.onExitVr.bind(this))
          const i = await t.getModule(o.default)
          ;(this.appPhaseModule = await t.getModule(c.default)),
            (this.hackWebVRVersion = await i
              .getApi()
              .getAppKey('SHOWCASE', 'webvr_version')),
            t.commandBinder.addBinding(d.s, async () =>
              this.hackLoadVrScript()
            ),
            t.commandBinder.addBinding(d.w, async () => this.hackEnterVrMode())
        }
        async maybeCacheVrDisplay() {
          const e = await n.H()
          e && (this.vrDisplay = e)
        }
        async hackEnterVrMode() {
          if (
            (await this.maybeCacheVrDisplay(),
            u.debug(`Presenting legacy webvr app to ${this.vrDisplay}`),
            this.vrDisplay)
          ) {
            u.info('Headset mounted'),
              this.engine.getModuleSync(a.default).disposeGui(),
              this.engine.deactivate(),
              this.explosivelyDisableGui()
            try {
              this.appPhaseModule.updateActiveApp(l.Mx.WEBVR)
            } catch (e) {
              throw Error("Error: Can't switch application mode at this time")
            }
          } else u.error('vrDisplay not found')
        }
        hackLoadVrScript() {
          const e = r.h('webvr') || this.hackWebVRVersion
          u.debug(`Loading legacy webvr app version ${e}`)
          const t = 'https://static.matterport.com/webvr/' + e + '/js/main.js'
          return new Promise(function (e, i) {
            const s = document.createElement('script')
            ;(s.type = 'text/javascript'),
              (s.src = t),
              (s.onload = e),
              document.head.appendChild(s)
          })
        }
        onExitVr() {
          this.vrDisplay.isPresenting ||
            (window.removeEventListener(
              'vrdisplaypresentchange',
              this.onExitVr
            ),
            u.info('Exiting VR'),
            this.hackUnload())
        }
        hackUnload() {
          let e = window.location.href
          ;-1 === window.location.search.indexOf('&qs=1') && (e += '&qs=1'),
            window.location.replace(e)
        }
        explosivelyDisableGui() {
          const e = document.getElementById('gui')
          e && e.remove()
        }
      }
    },
    18574: (e, t, i) => {
      'use strict'
      i.r(t), i.d(t, { default: () => DwellAnalytics })
      var s = i(47724),
        n = i(23847),
        r = i(59088),
        o = i(21479),
        a = i(35597),
        h = i(94329),
        l = i(62330),
        d = i(98292),
        c = i(31879),
        u = i(19674),
        p = i(87324)
      function g(e) {
        const t = (0, p.J5)(u.ep.toVisionQuaternion(e.rotation))
        return {
          position: (0, p.m)(u.ep.toVisionVector(e.position)),
          rotation: t,
          aspect: e.aspect(),
          isOrtho: e.isOrtho(),
          fovX: e.fovX(),
          fovY: e.fovY()
        }
      }
      function m(e) {
        return (0, c.U)(new Date(e))
      }
      class DwellAnalytics extends s.Y {
        constructor() {
          super(...arguments),
            (this.name = 'dwell-analytics'),
            (this.pendingDwellEvents = []),
            (this.onCameraChange = (0, l.P)((e) => {
              this.checkForDwellEvent(),
                e.clone(this.currentEvent.pose),
                (this.currentEvent.startTimeMs = Date.now()),
                this.scheduleDwellTimeOutEvent()
            }, 1e3)),
            (this.checkForDwellEvent = (e = !1) => {
              const { startTimeMs: t, viewmode: i } = this.currentEvent
              if (!t || this.appData.phase !== o.nh.PLAYING) return
              const s = Date.now(),
                n = s - t,
                r = {
                  pose: g(this.currentEvent.pose),
                  durationMs: n,
                  startTime: m(t),
                  endTime: m(s),
                  timedOut: e,
                  viewmode: i
                }
              this.trackDwellEvent(r)
            }),
            (this.onViewmodeUpdate = (e) => {
              e.value !== h.Ey.Transition &&
                (this.currentEvent.viewmode = (0, h.Ae)(e.value))
            }),
            (this.trackDwellEvent = (e) => {
              this.pendingDwellEvents.push(e), this.trackPendingDwellEvents()
            }),
            (this.trackPendingDwellEvents = (0, l.P)(() => {
              const e = { events: JSON.stringify(this.pendingDwellEvents) }
              ;(this.pendingDwellEvents = []),
                this.analytics.track('dwell_events', e)
            }, 5e3)),
            (this.onBlur = () => this.stopTrackingDwellTime(!1)),
            (this.stopTrackingDwellTime = (e = !1) => {
              this.checkForDwellEvent(e), delete this.currentEvent.startTimeMs
            }),
            (this.resumeTrackingDwellTime = () => {
              this.currentEvent.startTimeMs ||
                (this.currentEvent.startTimeMs = Date.now()),
                this.scheduleDwellTimeOutEvent()
            }),
            (this.throttledResumeTrackingDwellTime = (0, l.P)(
              this.resumeTrackingDwellTime,
              100
            )),
            (this.scheduleDwellTimeOutEvent = (0, d.D)(
              () => this.stopTrackingDwellTime(!0),
              15e3
            ))
        }
        async init(e, t) {
          ;([this.analytics, this.cameraData, this.appData, this.viewmodeData] =
            await Promise.all([
              t.getModule(n.default),
              t.market.waitForData(r.M_),
              t.market.waitForData(o.pu),
              t.market.waitForData(a.O)
            ])),
            (this.currentEvent = {
              pose: this.cameraData.pose.clone(),
              viewmode: (0, h.Ae)(null)
            }),
            this.bindings.push(
              this.cameraData.pose.onChanged(this.onCameraChange)
            ),
            this.bindings.push(
              this.viewmodeData.onPropertyChanged(
                'currentModeObservable',
                this.onViewmodeUpdate
              )
            ),
            window.addEventListener('blur', this.onBlur),
            window.addEventListener('focus', this.resumeTrackingDwellTime),
            window.addEventListener('keydown', this.resumeTrackingDwellTime),
            window.addEventListener(
              'touchcancel',
              this.resumeTrackingDwellTime
            ),
            window.addEventListener('touchstart', this.resumeTrackingDwellTime),
            window.addEventListener('touchend', this.resumeTrackingDwellTime),
            window.addEventListener(
              'touchmove',
              this.throttledResumeTrackingDwellTime
            ),
            window.addEventListener(
              'mousemove',
              this.throttledResumeTrackingDwellTime
            )
        }
        dispose(e) {
          super.dispose(e),
            window.removeEventListener('blur', this.onBlur),
            window.removeEventListener('focus', this.resumeTrackingDwellTime),
            window.removeEventListener('keydown', this.resumeTrackingDwellTime),
            window.removeEventListener(
              'touchcancel',
              this.resumeTrackingDwellTime
            ),
            window.removeEventListener(
              'touchstart',
              this.resumeTrackingDwellTime
            ),
            window.removeEventListener(
              'touchend',
              this.resumeTrackingDwellTime
            ),
            window.removeEventListener(
              'touchmove',
              this.throttledResumeTrackingDwellTime
            ),
            window.removeEventListener(
              'mousemove',
              this.throttledResumeTrackingDwellTime
            )
        }
      }
    },
    35165: (e, t, i) => {
      'use strict'
      i.r(t),
        i.d(t, {
          Group: () => $.Z,
          Grouper: () => $.h,
          MeasurementLabelBackgroundMesh: () => MeasurementLabelBackgroundMesh,
          MeasurementLabelRenderer: () => MeasurementLabelRenderer,
          MeasurementLineRenderer: () => MeasurementLineRenderer,
          MeasurementModeData: () => Y.X,
          MeasuringPhase: () => W.au,
          default: () => vt,
          labelVisible: () => W.Ph
        })
      var s = i(47724),
        n = i(96909),
        r = i(32306),
        o = i(17399),
        a = i(67627),
        h = i(26589),
        l = i(14092),
        d = i(4901),
        c = i(67394),
        u = i(24930),
        p = i(59088),
        g = i(27326),
        m = i(35597),
        w = i(88512),
        f = i(2212),
        v = i(17131),
        T = i(81122),
        y = i(7170),
        S = i(51058),
        P = i(27687),
        D = i(48711)
      const b = new f.Vector2(),
        M = new f.Vector3(),
        x = new f.Vector2(),
        I = new f.Vector2(),
        R = (e, t, i) => {
          const s = ((e, t, i) => (
            (0, P.q9)(i, e, x),
            (0, P.q9)(i, t, I),
            {
              pixelDistance: x.distanceTo(I),
              startScreenPosition: x,
              endScreenPosition: I
            }
          ))(e, t, i)
          return {
            screenPosition: ((e, t, i) => (
              M.copy(e).add(t).multiplyScalar(0.5), (0, P.q9)(i, M, b), b
            ))(e, t, i),
            rotation: C(x, I),
            pixelDistance: s.pixelDistance,
            startScreenPosition: s.startScreenPosition,
            endScreenPosition: s.endScreenPosition
          }
        },
        C = (e, t) => {
          const i = e.y - t.y,
            s = e.x - t.x
          let n = Math.atan2(i, s) * y.MN
          return (n = n >= 90 || n <= -90 ? n + 180 : n), n
        }
      var E = i(37342)
      const L = new w.Z('line-data')
      class LineDerivedDataFactory {
        constructor(
          e,
          t,
          i,
          s,
          n,
          r,
          o = () => ({
            lineVisibleByFeatureType: !0,
            labelVisibleByFeatureType: !0
          })
        ) {
          ;(this.cameraData = e),
            (this.viewmodeData = t),
            (this.floorsViewData = i),
            (this.isCurrentSweepAligned = s),
            (this.getUnits = n),
            (this.isFeatureEnabled = r),
            (this.visibleFilter = o),
            (this.derivedDataCache = {}),
            (this.dollhouseLineStyle = T.T.ThreeD),
            (this.setVisibilityFilter = (e) => {
              this.visibleFilter = e
            }),
            (this.defaultVisibilityFilter = () => {
              this.visibleFilter = () => ({
                lineVisibleByFeatureType: !0,
                labelVisibleByFeatureType: !0
              })
            }),
            (this.make = (e, t, i) => {
              const s = t(),
                {
                  start_position: n,
                  end_position: r,
                  visible: o,
                  floorId: a,
                  type: h,
                  text: l
                } = s,
                d = void 0 !== i ? i.opacity.value : 0,
                c = o && this.isFeatureEnabled(),
                u = c && this.visibleByFloorAndModes(a, h),
                p = 0 === d || (d === E.iV.LABEL_HIDDEN_OPACITY && u)
              if (i && p && (!c || !u)) return i
              let g = u,
                m = u
              if (u) {
                const t = this.visibleFilter(e)
                ;(g = g && t.lineVisibleByFeatureType),
                  (m = m && t.labelVisibleByFeatureType)
              }
              let w = 0
              const f = n.distanceTo(r),
                T = ((e, t = S.M.IMPERIAL) => {
                  let i = '0"'
                  switch (t) {
                    case S.M.IMPERIAL:
                      const { feet: t, inches: s } = (0, D.XJ)(e)
                      i = t > 0 ? `${t}' ${s}"` : `${s}"`
                      break
                    case S.M.METRIC:
                      i = `${e.toFixed(2)}m`
                  }
                  return i
                })(f, this.getUnits())
              if (m || !p) {
                const { width: e, height: t } = ((e, t = 10, i = 40) => ({
                    width: Math.max(9 * Math.max(e, 2) + t, i),
                    height: 18 + t
                  }))(l.length + T.length),
                  i = R(n, r, this.cameraData)
                this.tmpVec.copy(i.startScreenPosition).sub(i.endScreenPosition)
                let s =
                  Math.abs(this.tmpVec.y) < Math.abs(this.tmpVec.x) ? t : e
                E.iV.ALIGN_LABELS && ((s = e), (w = i.rotation)),
                  (m = m && i.pixelDistance > s)
              }
              let y
              const P = g && m ? 1 : g && !m ? E.iV.LABEL_HIDDEN_OPACITY : 0
              i
                ? ((y = i.opacity),
                  (y.endValue === P &&
                    g === i.visible &&
                    m === i.labelVisible) ||
                    y.modifyAnimation(y.value, P, E.iV.FADE_DURATION))
                : (y = new v.z(0, P, E.iV.FADE_DURATION))
              const b = {
                sid: e,
                rotation: w,
                labelVisible: m,
                visible: g,
                length: f,
                displayLength: T,
                labelContents: l.length > 0 ? `${T} ${l}` : T,
                opacity: y
              }
              return (
                (this.derivedDataCache[e] = {
                  getLineData: t,
                  previousDerivedData: b
                }),
                b
              )
            }),
            (this.update = (e) => {
              if (this.derivedDataCache[e]) {
                const { getLineData: t, previousDerivedData: i } =
                  this.derivedDataCache[e]
                return this.make(e, t, i)
              }
              L.warn(`data not found for ${e}`)
            }),
            (this.get = (e) => {
              if (this.derivedDataCache[e])
                return this.derivedDataCache[e].previousDerivedData
            }),
            (this.remove = (e) => {
              this.derivedDataCache[e] && delete this.derivedDataCache[e]
            }),
            (this.clear = () => {
              this.derivedDataCache = {}
            }),
            (this.visibleByFloorAndModes = (e, t) => {
              if (this.floorsViewData.transition.progress.active) return !1
              const i = this.viewmodeData.isInside(),
                s = this.viewmodeData.isFloorplan(),
                n = this.viewmodeData.isDollhouse(),
                r = this.floorsViewData.currentFloor,
                o = !r,
                a = !(!r || r.id !== e),
                h = e === this.floorsViewData.topFloorId,
                l = t === T.T.FloorplanOnly && s && (a || (h && o)),
                d = t === this.dollhouseLineStyle && n && (a || o)
              return (
                (t === T.T.ThreeD && i && this.isCurrentSweepAligned()) ||
                d ||
                l
              )
            }),
            (this.tmpVec = new f.Vector2())
        }
        setDollhouseLineStyle(e) {
          this.dollhouseLineStyle = e
        }
      }
      var F,
        k,
        A = i(33874),
        N = i(3248),
        O = i(55305),
        G = i(75892),
        z = i(21479),
        V = i(40688),
        U = i(62518),
        B = i(39712),
        Q = i(41911),
        _ = i(58878),
        H = i(13341),
        j = i(52247),
        q = i(26881),
        Z = i(81638),
        X = i(66157),
        W = i(60725),
        Y = i(38003),
        $ = i(14275),
        K = i(36371),
        J = i(78475),
        ee = i(44283)
      !(function (e) {
        ;(e[(e.ADDED = 0)] = 'ADDED'),
          (e[(e.REMOVED = 1)] = 'REMOVED'),
          (e[(e.UPDATED = 2)] = 'UPDATED'),
          (e[(e.COUNT = 3)] = 'COUNT')
      })(F || (F = {})),
        (function (e) {
          ;(e[(e.ADDED = 1)] = 'ADDED'),
            (e[(e.REMOVED = 2)] = 'REMOVED'),
            (e[(e.UPDATED = 4)] = 'UPDATED'),
            (e[(e.ALL = 7)] = 'ALL')
        })(k || (k = {}))
      const te = (e, t) => {
        const i = t & k.ADDED,
          s = t & k.REMOVED,
          n = t & k.UPDATED,
          r = {}
        let o
        return new ee.gm(
          () => e,
          (t) =>
            (o = e.onElementChanged(
              ((e) => (
                (r.onAdded = i ? e : void 0),
                (r.onRemoved = s ? e : void 0),
                (r.onUpdated = n ? e : void 0),
                r
              ))(t)
            )),
          (e) => {
            o && o.cancel()
          }
        )
      }
      var ie
      !(function (e) {
        ;(e[(e.x = 16711680)] = 'x'),
          (e[(e.y = 32768)] = 'y'),
          (e[(e.z = 255)] = 'z'),
          (e[(e.free = 16777215)] = 'free'),
          (e[(e.xz = 16711935)] = 'xz'),
          (e[(e.laser = 16724312)] = 'laser'),
          (e[(e.yellow = 16776960)] = 'yellow'),
          (e[(e.white = 16777215)] = 'white')
      })(ie || (ie = {}))
      var se = i(69626)
      class MeasurementLineRenderer {
        constructor(e, t, i, s, n, r, o = () => -1, a, h = 16777215) {
          ;(this.points = e),
            (this.createPointSubscription = t),
            (this.cameraData = i),
            (this.lineModule = s),
            (this.mainLayer = n),
            (this.lineLayer = r),
            (this.selectedGroup = o),
            (this.getLineDetails = a),
            (this.lineColor = h),
            (this.endpointGeometry = new f.PlaneBufferGeometry(1, 1)),
            (this.linePool = []),
            (this.groupToLines = {}),
            (this.pointToLines = {}),
            (this.activeLines = []),
            (this.cameraQuaternion = new f.Quaternion()),
            (this.cameraPosition = new f.Vector3()),
            (this.cameraProjection = new K.M()),
            (this.getLinesForPoint = (e) => {
              const t = []
              if (this.pointToLines[e])
                for (const i of this.pointToLines[e]) {
                  const e = i.getMesh(J.B.line),
                    { startIndex: s, endIndex: n, group: r } = e.userData
                  t.push({ endIndex: n, startIndex: s, line: i, group: r })
                }
              return t
            }),
            this.updateMaterialColors(this.lineColor),
            (this.dataSubs = [
              this.createPointSubscription(k.REMOVED, (e, t) => {
                this.resetLines()
              })
            ])
        }
        updateMaterialColors(e) {
          const t = E.V9.lineDefault
          ;(this.lineMaterial = this.lineModule.makeLineMaterial(e, !0, {
            linewidth: t
          })),
            (this.lineMaterial.stencilRef = 1),
            (this.lineMaterial.stencilFail = f.KeepStencilOp),
            (this.lineMaterial.stencilZFail = f.KeepStencilOp),
            (this.lineMaterial.stencilZPass = f.KeepStencilOp),
            (this.lineMaterial.stencilFunc = f.GreaterStencilFunc),
            (this.lineMaterial.stencilWrite = !0),
            (this.endpointMaterial = this.lineModule.makeEndpointMaterial(e))
          const i = {
            dashed: !0,
            dashSize: 0.025,
            gapSize: 0.05,
            linewidth: E.V9.dottedLineDefault
          }
          ;(this.dottedLineMaterial = this.lineModule.makeLineMaterial(
            e,
            !1,
            i
          )),
            (this.xLineMaterial = this.lineModule.makeLineMaterial(
              ie.x,
              !1,
              i
            )),
            (this.yLineMaterial = this.lineModule.makeLineMaterial(
              ie.y,
              !1,
              i
            )),
            (this.zLineMaterial = this.lineModule.makeLineMaterial(
              ie.z,
              !1,
              i
            )),
            (this.xzLineMaterial = this.lineModule.makeLineMaterial(
              ie.xz,
              !1,
              i
            ))
        }
        setLineOpacityByGroup(e, t) {
          const i = this.groupToLines[e]
          if (i) for (const e of i) e.opacity(t)
        }
        setLineOpacityByPoint(e, t) {
          const i = this.getLinesForPoint(e)
          if (i) for (const e of i) e.line.opacity(t)
        }
        resetLines() {
          for (const e of this.lines) e.opacity(0), e.hide()
          ;(this.groupToLines = {}),
            (this.pointToLines = {}),
            (this.lines.length = 0)
        }
        updateAllLines() {
          if (!(this.points.length < 1)) {
            for (let e = 0; e < this.points.length; e++) this.updateLine(e)
            for (const e in this.groupToLines) {
              const t = Number(e),
                i = this.groupToLines[t]
              for (const e of i) e.updateSelected(this.selectedGroup() === t)
            }
          }
        }
        init() {}
        dispose() {
          this.deactivate()
          for (const e of this.linePool) e.dispose()
          this.endpointGeometry.dispose(),
            this.dottedLineMaterial.dispose(),
            this.lineMaterial.dispose(),
            this.endpointMaterial.dispose(),
            this.xLineMaterial.dispose(),
            this.yLineMaterial.dispose(),
            this.zLineMaterial.dispose()
        }
        activate() {
          for (const e of this.dataSubs) e.renew()
        }
        deactivate() {
          for (const e of this.dataSubs) e.cancel()
          this.resetLines()
        }
        get lines() {
          return this.activeLines
        }
        get dottedMaterial() {
          return this.dottedLineMaterial
        }
        beforeRender() {
          this.cameraQuaternion.copy(this.cameraData.pose.rotation),
            this.cameraPosition.copy(this.cameraData.pose.position),
            this.cameraProjection.copy(this.cameraData.pose.projection)
        }
        get xMaterial() {
          return this.xLineMaterial
        }
        get yMaterial() {
          return this.yLineMaterial
        }
        get zMaterial() {
          return this.zLineMaterial
        }
        get xzMaterial() {
          return this.xzLineMaterial
        }
        render() {
          this.updateAllLines()
        }
        updateLine(e) {
          const t = this.points.get(e),
            i = this.points.get(e + 1),
            s =
              this.points.groupFromPointIndex(e) ===
              this.points.groupFromPointIndex(e + 1)
          t && i && s && this.setLinePosition(e, t, i)
        }
        setLinePosition(e, t, i) {
          let s = this.linePool[e]
          if (!s) {
            const n = this.points.groupFromPointIndex(e)
            if (!this.getLineDetails(n, e, e + 1).visible) return
            const r =
              E.V9.endpointDefault > 0.01
                ? this.endpointMaterial.clone()
                : void 0
            ;(s = this.lineModule.makeLine(
              t,
              i,
              this.lineMaterial.clone(),
              r,
              () => !(0, se.Pp)(this.cameraProjection)
            )),
              this.setupLine(s, e),
              s.setRenderLayer(this.mainLayer)
          }
          s.visible || this.setupLine(s, e),
            (this.linePool[e] = s),
            s.updateResolution(this.cameraData.width, this.cameraData.height),
            s.updatePositions(t, i),
            s.updateBillboard({
              rotation: this.cameraQuaternion,
              position: this.cameraPosition,
              projection: this.cameraProjection
            })
        }
        setupLine(e, t) {
          const i = this.points.groupFromPointIndex(t)
          e.children.forEach((e) => {
            ;(e.userData.startIndex = t),
              (e.userData.endIndex = t + 1),
              (e.userData.group = i),
              (e.layers.mask = this.mainLayer.mask)
          }),
            (e.getMesh(J.B.line).layers.mask = this.lineLayer.mask),
            this.activeLines.push(e),
            this.addLineToGroup(i, e),
            this.addLineToPoint(t, e),
            this.addLineToPoint(t + 1, e),
            e.show(),
            e.opacity(0)
        }
        addLineToGroup(e, t) {
          this.groupToLines[e] || (this.groupToLines[e] = []),
            this.groupToLines[e].push(t)
        }
        addLineToPoint(e, t) {
          this.pointToLines[e] || (this.pointToLines[e] = []),
            this.pointToLines[e].push(t)
        }
      }
      var ne = i(27408),
        re = i(60039),
        oe = i(12216),
        ae = i(35003),
        he = i(94610),
        le = i(24764)
      class MeasurementLabelBackgroundMesh extends f.Mesh {}
      class MeasurementLabelRenderer {
        constructor(e, t, i, s, n, r, o, a, h, l, d, c) {
          ;(this.points = e),
            (this.input = t),
            (this.mobile = i),
            (this.createPointSubscription = s),
            (this.cameraData = n),
            (this.renderLayer = r),
            (this.renderOrder = o),
            (this.textRenderer = a),
            (this.getLineDetails = h),
            (this.changeCursor = l),
            (this.getPhase = d),
            (this.setSelectedLine = c),
            (this.lengthCache = []),
            (this.meshPool = []),
            (this.textContainer = new f.Object3D()),
            (this.textGeometry = new f.PlaneBufferGeometry(1, 1)),
            (this.tmpMidpoint = new f.Vector3()),
            (this.tmpCamPos = new f.Vector3()),
            (this.cameraRotation = new f.Quaternion()),
            (this.cameraProjection = new K.M()),
            (this.cameraPosition = new f.Vector3())
          ;(this.dataSubs = [
            this.createPointSubscription(k.REMOVED, (e, t) => {
              const i = this.meshPool[t]
              i &&
                (this.input.unregisterMesh(i.collider),
                this.textContainer.remove(i),
                (this.meshPool[t] = null))
              for (
                let e = this.points.length - 1;
                e < this.lengthCache.length - 1;
                ++e
              )
                this.lengthCache[e] = -1
            }),
            this.input.registerMeshHandler(
              ae.R,
              le.s.isType(MeasurementLabelBackgroundMesh),
              (e, t) => {
                var i, s
                if (this.getPhase() === W.au.IDLE)
                  return (
                    this.setSelectedLine(
                      null ===
                        (s =
                          null === (i = null == t ? void 0 : t.parent) ||
                          void 0 === i
                            ? void 0
                            : i.userData) || void 0 === s
                        ? void 0
                        : s.groupIndex
                    ),
                    !0
                  )
              }
            )
          ]),
            this.mobile || this.dataSubs.push(...this.registerHoverHandlers())
        }
        registerHoverHandlers() {
          return [
            this.input.registerMeshHandler(
              he.z,
              le.s.isType(MeasurementLabelBackgroundMesh),
              () => {
                this.getPhase() === W.au.IDLE && this.changeCursor(l.C.FINGER)
              }
            ),
            this.input.registerMeshHandler(
              he.A,
              le.s.isType(MeasurementLabelBackgroundMesh),
              () => {
                this.changeCursor(l.C.DEFAULT)
              }
            )
          ]
        }
        reset() {
          for (const e of this.meshPool)
            e &&
              (this.input.unregisterMesh(e.collider),
              this.textContainer.remove(e))
          ;(this.meshPool = []), (this.lengthCache = [])
        }
        init() {}
        dispose() {
          this.textGeometry.dispose()
        }
        activate() {
          for (const e of this.dataSubs) e.renew()
        }
        deactivate() {
          for (const e of this.dataSubs) e.cancel()
          this.reset()
        }
        get container() {
          return this.textContainer
        }
        beforeRender() {
          const e = this.cameraData.pose
          this.cameraRotation.copy(e.rotation),
            this.cameraPosition.copy(e.position),
            this.cameraProjection.copy(e.projection)
          const t = (0, se.s1)(this.cameraProjection),
            i = (0, se.Pp)(this.cameraProjection),
            s = this.cameraData.height,
            n = this.cameraData.zoom(),
            r = this.cameraData.aspect()
          for (let e = 1; e < this.points.length; ++e) {
            const o = e - 1,
              a = this.points.groupFromPointIndex(e),
              h = this.getLineDetails(a, o, e)
            if (!h || a !== this.points.groupFromPointIndex(o)) {
              this.setMeshVisible(e, !1)
              continue
            }
            const l = this.points.get(o),
              d = this.points.get(e),
              c = this.setMeshVisible(e, h.labelVisible)
            if (!c) continue
            c.text !== h.labelContents && (c.text = h.labelContents)
            const u = this.cameraPosition.distanceTo(c.position)
            if (
              (this.updateMeshPose(
                c,
                l,
                d,
                this.cameraRotation,
                this.cameraPosition,
                u,
                h.rotation,
                i
              ),
              i || t)
            )
              c.scaleFactor = re.Hn.SCALE_DISTANCE * n
            else {
              const e = (0, P.D_)(
                  c.position,
                  this.cameraPosition,
                  this.cameraRotation,
                  this.cameraProjection.asThreeMatrix4()
                ),
                t = Math.abs(e.x)
              if (t < 1) {
                const e = (0, se.mY)(
                    this.cameraProjection,
                    this.cameraPosition,
                    c.position,
                    s,
                    re.Hn.SCALE
                  ),
                  i = ((0, ne.uZ)(r, 1, 2.5) + n) * re.Hn.SCALE_ASPECT,
                  o = 1 + re.Hn.SCALE_NDC - t * re.Hn.SCALE_NDC - i
                c.scaleFactor = Math.max(Math.min((1 / e) * o, 3), 0.001)
              } else c.scaleFactor = 0.001
            }
          }
        }
        setTextOpacityByPoint(e, t) {
          const i = this.meshPool[e]
          i && (i.opacity = t)
        }
        updateMeshPose(e, t, i, s, n, r, o, a) {
          this.tmpMidpoint.copy(t).add(i).multiplyScalar(0.5)
          const h = a
            ? (e) => this.tmpCamPos.copy(e).addScaledVector(oe.f.UP, 0.15)
            : (e) =>
                this.tmpCamPos
                  .copy(n)
                  .sub(e)
                  .setLength(0.15 * r)
                  .add(e)
          e.setPosition(this.tmpMidpoint, h), e.setOrientation(s, o)
        }
        render() {}
        setMeshVisible(e, t) {
          let i = this.meshPool[e]
          if (!i && t) {
            ;(i = this.textRenderer.createLabel()),
              i.setRenderLayer(this.renderLayer),
              (i.renderOrder = this.renderOrder),
              (i.opacity = 1),
              (i.visible = !1)
            const t = this.points.groupFromPointIndex(e)
            ;(i.userData.groupIndex = t),
              this.textContainer.add(i),
              this.input.registerMesh(i.collider, !1)
          }
          if (i) {
            const e = t ? 0.001 : E.iV.LABEL_HIDDEN_OPACITY
            if (((i.visible = i.opacity > e), !i.visible)) return null
          }
          return (this.meshPool[e] = i), i
        }
      }
      var de = i(84561),
        ce = i(1089),
        ue = i(66223),
        pe = i(69927),
        ge = i(44019),
        me = i(71682),
        we = i(57721),
        fe = i(3220),
        ve = i(48358)
      class GridPlaneCursor {
        constructor(e, t = de.o.ALL) {
          ;(this.scene = e),
            (this.layer = t),
            (this.supportsMobile = !0),
            (this.style = me.L.GridPlane),
            (this.alignToNormal = !0),
            (this.xzTex = (0, ue.p)(we)),
            (this.zyTex = (0, ue.p)(fe)),
            (this.bindings = []),
            (this.onOpacityUpdate = (e) => {
              this.container.children.forEach((t) => {
                t.isMesh && (t.material.opacity = Math.max(0, e.opacity.value))
              })
            }),
            (this.onPositionUpdate = (e, t) => {
              this.container.position.copy(e).addScaledVector(t, 0.005),
                this.alignToNormal && (0, se.J2)(this.container, e, t)
            }),
            (this.scale = (e) => {
              this.container.scale.set(e, e, e)
            }),
            (this.onRaycasterUpdate = (e) => {
              e.hit &&
                e.hit.face &&
                this.onPositionUpdate(e.hit.point.clone(), e.hit.face.normal)
            }),
            (this.container = new f.Group())
          const i = new f.PlaneGeometry(0.4, 0.4),
            s = {
              color: 16777215,
              side: f.DoubleSide,
              transparent: !0,
              depthTest: !0,
              depthWrite: !1
            }
          ;(this.xzTex.generateMipmaps = !1),
            (this.xzTex.minFilter = f.LinearFilter),
            (this.xzMaterial = new f.MeshBasicMaterial(
              Object.assign(Object.assign({}, s), {
                color: 65280,
                map: this.xzTex
              })
            )),
            (this.xzMaterial.premultipliedAlpha = !1)
          const n = new f.Mesh(i, this.xzMaterial)
          n.rotateOnAxis(oe.f.LEFT, Math.PI / 2),
            (this.zyTex.generateMipmaps = !1),
            (this.zyTex.minFilter = f.NearestFilter),
            (this.zyMaterial = new f.MeshBasicMaterial(
              Object.assign(Object.assign({}, s), { map: this.zyTex })
            )),
            (this.zyMaterial.premultipliedAlpha = !1)
          const r = new f.Mesh(i, this.zyMaterial)
          this.container.add(n, r),
            this.container.children.forEach((e) => {
              ;(e.renderOrder = ve.z.reticule),
                (e.layers.mask = this.layer.mask)
            })
        }
        init() {}
        render() {}
        dispose() {
          this.container.children.forEach((e) => {
            if (e.isMesh) {
              e.geometry.dispose()
              const t = e.material
              t.dispose(), t.map && t.map.dispose()
            }
          })
        }
        async activate(e) {
          const t = await e.market.waitForData(pe.Y),
            i = await e.market.waitForData(ge.P)
          this.bindings.push(
            t.onChanged(this.onOpacityUpdate),
            i.onChanged(this.onRaycasterUpdate)
          ),
            this.scene.add(this.container)
        }
        deactivate(e) {
          for (const e of this.bindings) e.cancel()
          ;(this.bindings.length = 0), this.scene.remove(this.container)
        }
        setVisible(e) {
          this.container.visible = e
        }
      }
      var Te = i(19674),
        ye = i(41659)
      class IntersectionVisualizer {
        constructor(e, t, i, s, n, r, o) {
          ;(this.mobile = e),
            (this.pointer = t),
            (this.sceneInfo = i),
            (this.renderToTexture = s),
            (this.getLayer = n),
            (this.issueCommand = r),
            (this.editing = !1),
            (this.editingStateChange = !1),
            (this.setOverlay = (e) => {
              this.issueCommand(new ye.u({ color: e ? ye.u.COLOR_DIM : null }))
            }),
            (this.setupCursorRenderCamera = () => {
              const e = new f.PerspectiveCamera(
                re.X7.perspective.fov,
                1,
                0.1,
                100
              )
              e.name = 'Cursor Peek Camera'
              const t = de.o.ALL,
                i = ['measurement-mode', 'measurement3d']
              for (const e of i) t.removeLayers(this.getLayer(e))
              ;(e.layers.mask = t.mask), e.updateProjectionMatrix()
              return {
                camera: e,
                update: (t, i, s) => {
                  ;(e.fov = t),
                    (e.near = i),
                    (e.far = s),
                    e.updateProjectionMatrix()
                }
              }
            })
          const a = (0, ue.p)(ce),
            h = new f.Vector2(),
            l = (e) => {
              const t = this.rttView.height,
                i = this.rttView.width,
                s = this.sceneInfo.cameraData
              let n = t / 2
              const r = -i / 2
              n = e.y < t / 2 + n ? t + n : -n
              const o = e.x + r,
                a = s.height - e.y - n
              return h.set(o, a)
            }
          ;(this.cursorMesh = new GridPlaneCursor(
            this.sceneInfo.scene,
            this.getLayer('cursor-mesh')
          )),
            this.cursorMesh.setVisible(!1)
          const d = new f.Vector3(),
            c = new f.Quaternion(),
            u = new f.Vector2()
          let p,
            g,
            m = o(),
            w = re.X7.perspective
          this.renderIntersection = (e, t, n) => {
            p ||
              ((g = this.setupCursorRenderCamera()),
              (p = g.camera),
              g.update(re.X7.perspective.fov, 0.1, 100)),
              m !== o() &&
                ((w = o() ? re.X7.ortho : re.X7.perspective),
                this.cursorMesh.scale(w.scale),
                g.update(w.fov, 0.1, 100),
                (m = o()))
            const r = this.editingStateChange ? 1 : re.X7.smoothness
            if (t) {
              if (
                (i.playerCamera.getWorldPosition(d),
                i.playerCamera.getWorldQuaternion(c),
                o())
              ) {
                const e = i.cameraData.zoom(),
                  s = (0, Te.dS)(
                    e,
                    w.thresholdClose,
                    w.thresholdFar,
                    w.offsetClose,
                    w.offsetFar
                  )
                p.position.copy(t.point).addScaledVector(oe.f.UP, s),
                  p.quaternion.copy(c)
              } else {
                const e = (0, Te.dS)(
                    t.distance,
                    w.thresholdClose,
                    w.thresholdFar,
                    w.offsetClose,
                    w.offsetFar
                  ),
                  i = d.sub(t.point).setLength(e).add(t.point)
                p.position.lerp(i, r), p.lookAt(t.point)
              }
              p.updateMatrixWorld(),
                re.E0 && this.setOverlay(!1),
                s.render(e, i.scene.scene, p),
                re.E0 && this.setOverlay(!0),
                u.lerp(l(n), r),
                s.renderToScreen(e, !1, u, a)
            }
            this.editingStateChange = !1
          }
        }
        init() {}
        dispose() {}
        activate() {
          this.sceneInfo.scene.addChild(a.a.Root, this.cursorMesh.container)
          const e = this.mobile
            ? re.ox.mobileSize
            : this.sceneInfo.cameraData.height > re.ox.highResThreshold
            ? re.ox.desktopSizeHighRes
            : re.ox.desktopSize
          this.rttView = this.renderToTexture.createRenderTarget2D(
            e,
            e,
            { format: f.RGBFormat },
            !1
          )
        }
        setMeasuringPhase(e) {
          const t = this.mobile ? !!W.Pj.mobile[e] : !!W.Pj.desktop[e]
          t !== this.editing &&
            ((this.editingStateChange = !0),
            (this.editing = t),
            this.cursorMesh.setVisible(this.editing))
        }
        deactivate() {
          this.sceneInfo.scene.removeChild(a.a.Root, this.cursorMesh.container),
            this.renderToTexture.disposeRenderTarget2D(this.rttView),
            (this.editing = !1)
        }
        beforeRender() {
          this.editing &&
            ((this.hit = this.mobile
              ? this.pointer.lastIntersection
              : this.pointer.getIntersection()),
            this.hit &&
              this.cursorMesh.onPositionUpdate(this.hit.point, this.hit.normal))
        }
        render() {
          if (this.editing && this.hit) {
            const { screenPosition: e } = (0, P.q9)(
              this.sceneInfo.cameraData,
              this.hit.point
            )
            this.renderIntersection(this.rttView, this.hit, e)
          }
        }
      }
      var Se,
        Pe = i(51245),
        De = i(36123),
        be = i(49399)
      !(function (e) {
        ;(e[(e.SnapPoint = 1)] = 'SnapPoint'),
          (e[(e.SnapLine = 2)] = 'SnapLine'),
          (e[(e.AxisAny = 3)] = 'AxisAny'),
          (e[(e.AxisX = 4)] = 'AxisX'),
          (e[(e.AxisY = 5)] = 'AxisY'),
          (e[(e.AxisZ = 6)] = 'AxisZ'),
          (e[(e.Mesh = 7)] = 'Mesh'),
          (e[(e.RoomMesh = 8)] = 'RoomMesh'),
          (e[(e.LinePoint = 9)] = 'LinePoint'),
          (e[(e.LineSegment = 10)] = 'LineSegment')
      })(Se || (Se = {}))
      class SnapAxisLine3 extends be.FM {
        constructor(e, t, i) {
          super(e, t), (this.featureType = i)
        }
      }
      class SnapUserLine3 extends be.FM {
        constructor(e, t, i) {
          super(e, t), (this.featureType = i)
        }
      }
      const Me = {
        [oe.e.UP]: Se.AxisY,
        [oe.e.DOWN]: Se.AxisY,
        [oe.e.FORWARD]: Se.AxisZ,
        [oe.e.BACK]: Se.AxisZ,
        [oe.e.LEFT]: Se.AxisX,
        [oe.e.RIGHT]: Se.AxisX,
        [oe.e.HORIZONTAL_PLANE]: Se.AxisY,
        NONE: void 0
      }
      var xe
      !(function (e) {
        ;(e[(e.UserAxis = 1)] = 'UserAxis'),
          (e[(e.UserPoint = 2)] = 'UserPoint'),
          (e[(e.UserLine = 3)] = 'UserLine'),
          (e[(e.ModelFeature = 4)] = 'ModelFeature')
      })(xe || (xe = {}))
      const Ie = {
        [Se.LinePoint]: xe.UserPoint,
        [Se.LineSegment]: xe.UserLine,
        [Se.AxisAny]: xe.UserAxis,
        [Se.AxisX]: xe.UserAxis,
        [Se.AxisY]: xe.UserAxis,
        [Se.AxisZ]: xe.UserAxis,
        [Se.Mesh]: xe.ModelFeature,
        [Se.RoomMesh]: xe.ModelFeature,
        [Se.SnapLine]: xe.ModelFeature,
        [Se.SnapPoint]: xe.ModelFeature
      }
      class ConstrainedHit {
        constructor(e, t, i) {
          ;(this.constraint = t),
            (this.point = new f.Vector3()),
            (this.normal = new f.Vector3()),
            Re(e)
              ? this.updateFromIntersection(e, t)
              : Ce(e) && i && this.updateFromSnapIntersection(e, t, i),
            (this.source = e)
        }
        updatePoint(e) {
          return this.point.copy(e), this.source.point.copy(e), this
        }
        updateFromIntersection(e, t) {
          return (
            (this.source = e),
            this.updateContents(
              t,
              e.point,
              e.face.normal,
              e.distance,
              e.object
            ),
            this
          )
        }
        updateFromSnapIntersection(e, t, i) {
          return (
            (this.source = e),
            this.updateContents(t, e.point, i, e.distance, e.object),
            this
          )
        }
        copy({ constraint: e, point: t, normal: i, distance: s, object: n }) {
          this.updateContents(e, t, i, s, n)
        }
        clone() {
          return new ConstrainedHit(this.source, this.constraint)
        }
        updateContents(e, t, i, s, n) {
          ;(this.constraint = e),
            this.point.copy(t),
            this.normal.copy(i),
            (this.distance = s),
            (this.object = n),
            Pe.$4.hasRoomId(n)
              ? ((this.roomId = n.roomId), (this.floorId = n.floorId))
              : Pe.$4.hasFloorId(n) &&
                ((this.floorId = n.floorId), (this.roomId = null)),
            (this.featureType = ((e) => {
              if (e)
                return 'featureType' in e && void 0 !== e.featureType
                  ? e.featureType
                  : e instanceof f.Vector3 || e instanceof be.UQ
                  ? Se.SnapPoint
                  : Pe.$4.isRoomMesh(e)
                  ? Se.RoomMesh
                  : e instanceof De.S
                  ? Se.Mesh
                  : e instanceof f.Line3 || e instanceof be.FM
                  ? Se.SnapLine
                  : void 0
            })(n))
        }
      }
      const Re = (e) =>
          e && 'face' in e && void 0 !== e.face && Pe.$4.hasFloorId(e.object),
        Ce = (e) =>
          e && 'isLineOctreeIntersection' in e && Pe.$4.hasFloorId(e.object),
        Ee = (() => {
          class MockedRoom extends f.Object3D {
            constructor(e, t) {
              super(), (this.floorId = e), (this.roomId = t)
            }
          }
          return (e, t, i, s, n) => ({
            point: e,
            object: new MockedRoom(s, n),
            face: { a: 0, b: 1, c: 2, normal: t, materialIndex: 0 },
            distance: i
          })
        })()
      var Le = i(13188),
        Fe = i(14063),
        ke = i(76863),
        Ae = i(51869),
        Ne = i(76870)
      const Oe = (e) =>
        e instanceof ae.R
          ? e.button === Ne.MP.PRIMARY
          : e.buttons === Ne.r3.PRIMARY
      class MeasurementInput extends f.Mesh {
        constructor(e, t, i, s, n, r, o, a, h, l, d, c) {
          super(),
            (this.pointGroups = e),
            (this.input = t),
            (this.cameraData = i),
            (this.mobile = s),
            (this.changeCursor = n),
            (this.getPhase = r),
            (this.changePhase = o),
            (this.restorePreviousPhase = a),
            (this.setSelectedLine = h),
            (this.getSelected = l),
            (this.onDragStart = d),
            (this.onDragEnd = c),
            (this.inputSubscriptions = []),
            (this.groupVisible = []),
            (this.raycast = (() => {
              const e = new f.Vector3()
              return (t, i) => {
                const { pose: s, width: n } = this.cameraData,
                  r = 0.005 * n,
                  o = s.projection.asThreeMatrix4(),
                  a = s.position
                let h,
                  l = 0,
                  d = 0
                for (let i = 0; i < this.pointGroups.groupCount; ++i) {
                  const s = this.pointGroups.getGroup(i)
                  if (
                    !(
                      void 0 !== this.editingGroup && this.editingGroup !== i
                    ) &&
                    this.groupVisible[i]
                  ) {
                    for (let c = 0; c < s.count - 1; ++c) {
                      const u = s.get(c),
                        p = s.get(c + 1)
                      if (u && p) {
                        const s = t.ray.distanceSqToSegment(u, p, void 0, e),
                          c = a.distanceTo(e)
                        let g = (0, se._U)(c, o, n) * r
                        if (((g *= g), s < g)) {
                          let n,
                            r = e
                          this.editingPointIndex
                            ? (n = this.editingPointIndex)
                            : u.distanceToSquared(e) < 2 * g
                            ? ((n = d), (r = u))
                            : p.distanceToSquared(e) < 2 * g &&
                              ((n = d + 1), (r = p)),
                            (!h || s < l) &&
                              ((h = {
                                distance: t.ray.origin.distanceTo(r),
                                point: r,
                                object: this,
                                instanceId: i,
                                index: n
                              }),
                              (l = s))
                        }
                      }
                      d++
                    }
                    d++
                  } else d += s.count
                }
                h && i.push(h)
              }
            })()),
            this.inputSubscriptions.push(...this.registerCommonInput()),
            s || this.inputSubscriptions.push(...this.registerHoverInput()),
            this.deactivate()
        }
        activate() {
          this.input.registerMesh(this, !1),
            this.inputSubscriptions.forEach((e) => e.renew())
        }
        deactivate() {
          this.input.unregisterMesh(this),
            this.inputSubscriptions.forEach((e) => e.cancel())
        }
        dispose() {
          this.deactivate()
        }
        setEditingGroup(e) {
          this.editingGroup = e
        }
        setGroupVisible(e, t) {
          this.groupVisible[e] = t
        }
        validJoint(e) {
          return !!e && void 0 !== e.index
        }
        registerHoverInput() {
          return [
            this.input.registerMeshHandler(
              he.z,
              le.s.isType(MeasurementInput),
              (e, t, i) => {
                this.getPhase() === W.au.IDLE &&
                  this.changeCursor(
                    i && void 0 !== i.index ? l.C.GRAB : l.C.FINGER
                  )
              }
            ),
            this.input.registerMeshHandler(
              he.A,
              le.s.isType(MeasurementInput),
              (e, t, i) => {
                this.getPhase() === W.au.IDLE && this.changeCursor(l.C.DEFAULT)
              }
            )
          ]
        }
        registerCommonInput() {
          return [
            this.input.registerMeshHandler(
              ae.R,
              le.s.isType(MeasurementInput),
              (e, t, i) => {
                if (!Oe(e)) return !1
                if (this.getPhase() !== W.au.IDLE) return !1
                const s = i && void 0 !== i.instanceId ? i.instanceId : -1,
                  n = this.getSelected() === s ? -1 : s
                return this.setSelectedLine(n), !0
              }
            ),
            this.input.registerMeshHandler(
              Ae._t,
              le.s.isType(MeasurementInput),
              (e, t, i) =>
                !!Oe(e) &&
                !!W.WN[this.getPhase()] &&
                (!this.validJoint(i) ||
                  !i ||
                  void 0 === i.instanceId ||
                  (this.getPhase() === W.au.EDITING ||
                    ((this.editingPointIndex = i.index),
                    this.onDragStart(i.instanceId),
                    this.setSelectedLine(i.instanceId),
                    this.changePhase(W.au.EDITING),
                    this.mobile || this.changeCursor(l.C.GRABBING)),
                  !0))
            ),
            this.input.registerMeshHandler(
              Ae._R,
              le.s.isType(MeasurementInput),
              (e, t, i) =>
                this.getPhase() === W.au.EDITING &&
                ((this.editingPointIndex = void 0),
                this.restorePreviousPhase(),
                this.onDragEnd(),
                this.mobile || this.changeCursor(l.C.DEFAULT),
                !0)
            )
          ]
        }
      }
      const Ge = new w.Z('snapping')
      class SnappablePointer {
        constructor(e, t, i, s, n) {
          ;(this.raycaster = e),
            (this.getConstraintStyle = t),
            (this.floorsViewData = s),
            (this.viewmodeData = n),
            (this.origin = null),
            (this.planeNormal = new f.Vector3()),
            (this.plane = new f.Plane()),
            (this.ray = new f.Ray()),
            (this.originChangedListeners = []),
            (this.registeredSnapFeatures = {
              [xe.UserAxis]: [],
              [xe.UserLine]: [],
              [xe.UserPoint]: [],
              [xe.ModelFeature]: []
            }),
            (this.clearOrigin = () => {
              ;(this.origin = null),
                this.originChangedListeners.forEach((e) => e(null))
            }),
            (this.setOrigin = (e, t = !1) => {
              ;(this.origin && !t) ||
                ((this.origin = e),
                this.plane.setFromNormalAndCoplanarPoint(
                  this.origin.normal,
                  this.origin.point
                ),
                this.originChangedListeners.forEach((e) => e(this.origin)),
                Ge.debug('Updating origin', this.origin, { forceUpdate: t }))
            }),
            (this.setOriginFromPointer = (e) => {
              if (this.origin) return
              const t = this.getMeshIntersection()
              if (!t) return
              const i = new ConstrainedHit(t, this.getConstraintStyle())
              e && i.updatePoint(e), this.setOrigin(i, !0)
            }),
            (this.snapFeatures = (e) =>
              this.registeredSnapFeatures[e].reduce(
                (e, t) => e.concat(t.features),
                []
              )),
            (this.addSnapFeatures = (e, t, i) => {
              const s = Ie[t]
              this.registeredSnapFeatures[s].push({ owner: e, features: i }),
                Ge.debug(`Adding ${i.length} snap feature groups`, Se[t], t)
            }),
            (this.removeSnapFeatures = (e, t) => {
              const i = Ie[t],
                s = this.registeredSnapFeatures[i].findIndex(
                  (t) => t.owner === e
                )
              if (-1 !== s) {
                const e = this.registeredSnapFeatures[i].splice(s, 1)
                Ge.debug(`Removing ${e.length} snap feature groups`, Se[t], t)
              } else
                Ge.debug(
                  `removeTemporarySnapFeature: ${t} ${Se[t]} not found from`,
                  e,
                  this.registeredSnapFeatures
                )
            }),
            (this.filters = {
              nop: (e) => !0,
              userPoints: (e) => {
                if (void 0 === e.object) return !1
                if ((t = e.object) && t instanceof f.Vector3)
                  for (const t of this.snapFeatures(xe.UserPoint))
                    if (t.equals(e.object)) return !0
                var t
                return !1
              },
              userLines: (e) => {
                if (void 0 === e.object) return !1
                if (
                  ((t = e.object) && 'isSnapAxisLine3' in t) ||
                  'isSnapUserLine3' in t ||
                  'isSnapLine3' in t ||
                  ('start' in t && 'end' in t && 'closestPointToPoint' in t)
                ) {
                  for (const t of this.snapFeatures(xe.UserLine))
                    if (t.equals(e.object)) return !0
                  for (const t of this.snapFeatures(xe.UserAxis))
                    if (t.equals(e.object)) return !0
                }
                var t
                return !1
              },
              userFeatures: (e) =>
                this.filters.userPoints(e) || this.filters.userLines(e)
            }),
            (this.meshSnapRadius = i ? re.Oq.mobile : re.Oq.desktop)
        }
        preload() {
          this.raycaster.snapping.preloadMeshSnapping()
        }
        getMeshIntersection(e) {
          let t,
            i = null,
            s = !1
          if (
            (e && e.origin && e.normal
              ? ((s = !0),
                (t = this.raycaster.picking.cast(e.origin, e.normal)))
              : (t = this.raycaster.pointer.cast()),
            (i = t[0]),
            this.viewmodeData.isFloorplan() && i && !s)
          ) {
            i = t.filter((e) => !(e.object instanceof MeasurementInput))[0]
            const e = this.floorsViewData.getHighestVisibleFloor(),
              s = Pe.$4.matchesFloorId(e.id)
            !(!i || (Re(i) && s(i.object))) &&
              (i = Ee(i.point, new f.Vector3(0, 1, 0), i.distance, e.id, null)),
              (i.point.y = e.boundingBox.max.y),
              i.face && i.face.normal.set(0, 1, 0)
          } else i = t.filter((e) => (0, ke.Pv)(e.object))[0]
          return Re(i) ? i : null
        }
        getIntersection(e) {
          const t = this.getMeshIntersection(e)
          if (!t) return null
          this.cachedHit ||
            (this.cachedHit = new ConstrainedHit(t, this.getConstraintStyle()))
          const i = this.cachedHit.updateFromIntersection(
              t,
              this.getConstraintStyle()
            ),
            s = this.raycaster.pointer.pointerRay
          this.ray.set(s.origin, s.direction), this.planeNormal.copy(i.normal)
          switch (this.getConstraintStyle()) {
            case Le.l1.Free:
              return i
            case Le.l1.Axes:
              return this.lockToWorldAxes(i)
            case Le.l1.PlanarAxes:
              const e = [
                ...this.snapFeatures(xe.UserAxis),
                ...this.snapFeatures(xe.UserLine),
                ...this.snapFeatures(xe.UserPoint)
              ]
              return this.softSnapToEdges(i, e, this.filters.userFeatures)
            case Le.l1.Edges:
              const t = [
                ...this.snapFeatures(xe.UserLine),
                ...this.snapFeatures(xe.UserPoint)
              ]
              return this.softSnapToEdges(i, t, this.filters.nop)
            case Le.l1.EdgesAndPlanarAxes:
              const s = [
                ...this.snapFeatures(xe.UserAxis),
                ...this.snapFeatures(xe.UserLine),
                ...this.snapFeatures(xe.UserPoint)
              ]
              return this.softSnapToEdges(i, s, this.filters.nop)
          }
          return i
        }
        get lastIntersection() {
          return this.cachedHit
        }
        onOriginChanged(e, t = !1) {
          const i = {
            renew: () => {
              this.originChangedListeners.push(e)
            },
            cancel: () => {
              ;(0, Fe.b)(this.originChangedListeners, e)
            }
          }
          return t && i.renew(), i
        }
        lockToWorldAxes(e) {
          if (this.origin) {
            const t = (0, Le.r2)(this.origin.point, e.point, Le.l1.Axes)
            return (
              this.cachedHit.copy(e),
              this.cachedHit.point.copy(t.position),
              (this.cachedHit.constraint =
                'NONE' !== t.axisName ? Le.l1.Axes : Le.l1.Free),
              (this.cachedHit.featureType = Me[t.axisName]),
              this.cachedHit
            )
          }
          return e
        }
        softSnapToEdges(e, t, i) {
          const s = this.origin ? this.origin.point : e.point,
            n = this.origin ? this.origin.normal : e.normal
          this.raycaster.snapping.add(...t)
          const r = this.raycaster.snapping
              .cast(this.ray, this.meshSnapRadius, s, n)
              .filter(i),
            o = this.raycaster.snapping.pick(this.ray, this.meshSnapRadius, r)
          return (
            this.raycaster.snapping.remove(...t),
            o
              ? (this.cachedHit.updateFromSnapIntersection(
                  o,
                  this.getConstraintStyle(),
                  n
                ),
                this.cachedHit)
              : e
          )
        }
      }
      var ze = i(98292)
      class SnappablePointUpdater {
        constructor(e, t, i, s) {
          ;(this.points = e),
            (this.createPointSubscription = t),
            (this.pointer = i),
            (this.mobileCreateHackJob = s),
            (this.subscriptions = []),
            (this.lineSegments = []),
            (this.updateSnapping = (e) => {
              this.lineSegments.length > 0 &&
                (this.pointer.removeSnapFeatures(this, Se.LineSegment),
                (this.lineSegments.length = 0))
              for (let t = 0; t < this.points.length; t++)
                if (
                  t !== e &&
                  t !== e - 1 &&
                  t !== e + 1 &&
                  !this.points.isStartIndex(t)
                ) {
                  const e = this.points.get(t),
                    i = this.points.get(t - 1)
                  this.lineSegments.push(
                    new SnapUserLine3(i, e, Se.LineSegment)
                  )
                }
              this.lineSegments.length > 0 &&
                this.pointer.addSnapFeatures(
                  this,
                  Se.LineSegment,
                  this.lineSegments
                )
            })
        }
        init() {}
        dispose() {}
        activate(e) {
          let t = -1,
            i = -1
          const s = (0, ze.D)(() => this.updateSnapping(this.points.length), 16)
          this.subscriptions.push(
            this.createPointSubscription(k.ADDED, s, !0),
            this.createPointSubscription(k.REMOVED, s, !0),
            this.createPointSubscription(
              k.UPDATED,
              (e, s) => {
                s === t ||
                  (this.mobileCreateHackJob() && s === i) ||
                  (this.updateSnapping(s), (i = t), (t = s))
              },
              !0
            )
          )
        }
        deactivate() {
          this.subscriptions.forEach((e) => e.cancel()),
            (this.subscriptions.length = 0),
            this.pointer.removeSnapFeatures(this, Se.LinePoint),
            this.pointer.removeSnapFeatures(this, Se.LineSegment)
        }
        beforeRender() {}
        render() {}
      }
      class MeasurementJointEditor {
        constructor(e, t, i, s, n, r) {
          ;(this.points = e),
            (this.pointer = i),
            (this.getPhase = s),
            (this.onDrag = n),
            (this.onDragEnd = r),
            (this.inputSubscriptions = []),
            (this.onDragBegin = (e, t, i) => {
              if (!W.q8[this.getPhase()]) return !1
              if (!i || void 0 === i.index) return !1
              const s = this.points.isStartIndex(i.index)
                  ? i.index + 1
                  : i.index - 1,
                n = this.points.get(s)
              return (
                this.pointer.clearOrigin(),
                this.pointer.setOriginFromPointer(n),
                !0
              )
            }),
            (this.onDragEndEvent = () =>
              !!W.q8[this.getPhase()] &&
              (this.onDragEnd(), this.pointer.clearOrigin(), !0)),
            (this.onDragEvent = (e, t, i) => {
              if (e.buttons !== Ne.r3.PRIMARY) return !1
              if (!W.q8[this.getPhase()]) return !1
              if (!i || void 0 === i.index || void 0 === i.instanceId) return !1
              const s = this.pointer.getIntersection()
              return (
                s && this.points.update(i.index, s.point),
                this.onDrag(i.instanceId),
                !0
              )
            }),
            this.inputSubscriptions.push(
              t.registerMeshHandler(
                Ae.E0,
                le.s.isType(MeasurementInput),
                this.onDragBegin
              ),
              t.registerMeshHandler(
                Ae._t,
                le.s.isType(MeasurementInput),
                this.onDragEvent
              ),
              t.registerMeshHandler(
                Ae._R,
                le.s.isType(MeasurementInput),
                this.onDragEndEvent
              )
            ),
            this.deactivate()
        }
        activate() {
          for (const e of this.inputSubscriptions) e.renew()
        }
        deactivate() {
          for (const e of this.inputSubscriptions) e.cancel()
        }
      }
      var Ve = i(49340)
      class MeasurementLineStyler {
        constructor(e, t, i, s, n, r, o) {
          ;(this.lines = e),
            (this.getLinesForPoint = t),
            (this.editingMaterial = i),
            (this.createPointSubscription = s),
            (this.getPhase = r),
            (this.getSelected = o),
            (this.bindings = []),
            (this.onDragEnd = (e) => {
              for (const e of this.lines) e.restoreLineMaterial()
            }),
            (this.onClick = (e, t, i) => {
              if (this.getPhase() !== W.au.IDLE) return !1
              for (const e of this.lines) e.restoreLineMaterial()
              if (!i || void 0 === i.index) return !1
              if (e.down) {
                const e = i.index
                void 0 !== e && this.styleLines(e)
              }
              return !1
            }),
            (this.styleLines = (e) => {
              const t = this.getLinesForPoint(e)
              for (const e of t)
                e.group === this.getSelected() &&
                  e.line.overrideLineMaterial(this.editingMaterial)
            }),
            this.bindings.push(
              n.registerMeshHandler(
                Ve.er,
                le.s.isType(MeasurementInput),
                this.onClick
              ),
              n.registerUnfilteredHandler(Ae._R, this.onDragEnd),
              ...this.setupLineStyler(this.createPointSubscription)
            ),
            this.deactivate()
        }
        activate() {
          for (const e of this.bindings) e.renew()
        }
        deactivate() {
          for (const e of this.bindings) e.cancel()
        }
        setupLineStyler(e) {
          return [
            e(
              k.ADDED,
              () => {
                const e = this.lines[this.lines.length - 1]
                e && e.restoreLineMaterial()
              },
              !0
            ),
            e(
              k.UPDATED,
              (e, t) => {
                this.styleLines(t)
              },
              !0
            )
          ]
        }
      }
      var Ue = i(33665),
        Be = i(53149)
      class MeasurementCreator {
        constructor(e, t, i, s, n, r, o, a, h) {
          ;(this.points = e),
            (this.setSelected = t),
            (this.pointer = i),
            (this.changePhase = s),
            (this.getPhase = n),
            (this.isFloorplan = r),
            (this.currentFloorId = o),
            (this.currentRoomId = a),
            (this.inferRoomAssociation = h),
            (this.id = MeasurementCreator),
            (this.onGroupCreated = (e) => null),
            (this.onGroupAddPoint = () => null),
            (this.onDone = () => null),
            (this.onEdit = (e) => null),
            (this.previousPhase = W.au.IDLE),
            (this.currentLinePoints = 0),
            (this.previousPoint = new f.Vector3()),
            (this.inputSubscriptions = []),
            (this.log = new w.Z('measurement-creator')),
            (this.createNewLine = (e) => {
              const t = this.inferRoomAssociation(e.point),
                i = e.roomId || t.roomId || this.currentRoomId() || null,
                s = e.floorId || t.floorId || this.currentFloorId()
              if (
                (this.log.debug(
                  `Starting measurement: floorId="${s}" roomId="${i}"`
                ),
                !s)
              )
                throw new Be.H(`Cannot create new line on invalid floor '${s}'`)
              const n = {
                  visible: !0,
                  roomId: i,
                  floorId: s,
                  type: this.isFloorplan() ? T.T.FloorplanOnly : T.T.ThreeD,
                  text: '',
                  created: new Date(),
                  modified: new Date()
                },
                r = this.points.startGroup(n)
              ;(this.currentGroup = r),
                this.points.push(e.point),
                (this.currentLinePoints = 1),
                this.setSelected(r)
              const o = this.points.getGroup(r)
              this.onGroupCreated(o.info.sid), this.pointer.setOrigin(e, !0)
            }),
            (this.addPointToLine = (e) => {
              this.previousPoint.copy(e.point),
                this.points.push(e.point),
                ++this.currentLinePoints,
                this.onGroupAddPoint(),
                this.pointer.setOrigin(e, !0)
            }),
            (this.updateLastPoint = (e) => {
              this.points.update(this.points.length - 1, e.point)
            }),
            (this.getIntersection = (e) => this.pointer.getIntersection(e)),
            (this.setPhase = (e) => {
              const t = this.getPhase()
              e !== t && ((this.previousPhase = t), this.changePhase(e))
            }),
            (this.restorePreviousPhase = () => {
              this.setPhase(this.previousPhase)
            })
        }
        start() {
          if (this.getPhase() === W.au.IDLE) {
            this.previousPoint.set(1e3, 1e3, 1e3),
              this.setPhase(W.au.CREATING),
              this.setSelected(-1)
            for (const e of this.inputSubscriptions) e.renew()
          }
        }
        cancelSubs() {
          for (const e of this.inputSubscriptions) e.cancel()
        }
        stop() {
          this.cancelSubs(),
            (this.currentLinePoints = 0),
            this.setSelected(-1),
            this.setPhase(W.au.IDLE),
            this.pointer.clearOrigin(),
            this.onDone()
        }
      }
      class MeasurementCreatorMobile extends MeasurementCreator {
        constructor(e, t, i, s, n, r, o, a, h, l, d, c, u, p) {
          super(e, t, s, n, h, d, c, u, p),
            (this.setCreatePointProgress = r),
            (this.updateCreatePointHit = o),
            (this.toggleCameraMovement = a),
            (this.continuous = l),
            (this.onLongPressSuccess = (e) => {
              this.log.debug(
                'onLongPressSuccess while in phase:',
                W.au[this.getPhase()]
              ),
                this.getPhase() === W.au.CREATING
                  ? (this.createNewLine(e), this.addPointToLine(e))
                  : this.getPhase() === W.au.CREATING_NEXT_POINT &&
                    (this.continuous()
                      ? (this.updateLastPoint(e), this.addPointToLine(e))
                      : this.updateLastPoint(e)),
                this.setPhase(W.au.POINT_PLACED)
            }),
            (this.onLongPressStart = (e) => {
              if (
                e.buttons === Ne.r3.PRIMARY &&
                (this.getPhase() === W.au.CREATING ||
                  this.getPhase() === W.au.CREATING_NEXT_POINT)
              ) {
                const e = this.getIntersection()
                e &&
                  (this.previousPoint.equals(e.point) ||
                    (this.setPhase(W.au.CONFIRMING_POINT),
                    this.toggleCameraMovement(!1),
                    this.setCreatePointProgress(
                      Date.now(),
                      MeasurementCreatorMobile.longPressCreateThreshold
                    ),
                    this.updateCreatePointHit(e),
                    this.previousPhase === W.au.CREATING_NEXT_POINT &&
                      (this.updateLastPoint(e),
                      this.toggleLastPointDraggable(!1)),
                    (this.creatingPointTimeout = window.setTimeout(() => {
                      this.restorePreviousPhase(),
                        this.onLongPressSuccess(e),
                        this.toggleLastPointDraggable(!0)
                    }, MeasurementCreatorMobile.longPressCreateThreshold))))
              }
            }),
            (this.onLongPressEnd = () => {
              this.getPhase() === W.au.CONFIRMING_POINT &&
                (this.log.debug('onLongPressEnd, cancelling confirmation'),
                this.setCreatePointProgress(
                  0,
                  MeasurementCreatorMobile.longPressCreateThreshold
                ),
                window.clearTimeout(this.creatingPointTimeout),
                this.toggleCameraMovement(!0),
                this.restorePreviousPhase()),
                this.getPhase() === W.au.CREATING_NEXT_POINT &&
                  this.points.update(
                    this.points.length - 1,
                    this.points.get(this.points.length - 2)
                  ),
                this.setPlacedtoCreatePhase()
            }),
            (this.onDrag = () => {
              const e = this.getIntersection()
              e &&
                (this.setPlacedtoCreatePhase(),
                this.setPhase(W.au.EDITING),
                this.previousPhase === W.au.CREATING_NEXT_POINT
                  ? this.updateLastTwoPoints(e)
                  : this.previousPhase === W.au.CREATING &&
                    this.updateLastPoint(e))
            }),
            (this.onDragEnd = () => {
              this.getPhase() === W.au.EDITING && this.restorePreviousPhase(),
                (this.getPhase() !== W.au.CREATING &&
                  this.getPhase() !== W.au.CREATING_NEXT_POINT) ||
                  (this.toggleLastPointDraggable(!1),
                  this.toggleCameraMovement(!0))
            }),
            (this.toggleLastPointDraggable = (e) => {
              e
                ? (this.dragSub.renew(), this.dragEndSub.renew())
                : (this.dragSub.cancel(), this.dragEndSub.cancel())
            }),
            (this.updateLastTwoPoints = (e) => {
              this.points.update(this.points.length - 1, e.point),
                this.points.update(this.points.length - 2, e.point)
            }),
            (this.dragSub = i(Ae._t, this.onDrag)),
            (this.dragEndSub = i(Ae._R, this.onDragEnd)),
            this.inputSubscriptions.push(
              i(Ue.Vh, this.onLongPressStart),
              i(Ue.pt, this.onLongPressEnd)
            ),
            this.dragSub.cancel(),
            this.dragEndSub.cancel(),
            this.cancelSubs()
        }
        start() {
          super.start()
        }
        stop() {
          if (this.getPhase() === W.au.CREATING_NEXT_POINT)
            if (this.continuous()) this.points.pop()
            else {
              const e = this.points.getGroup(this.currentGroup)
              this.points.removeFromIdx(e.startIndex)
            }
          super.stop()
        }
        setPlacedtoCreatePhase() {
          this.getPhase() === W.au.POINT_PLACED &&
            (this.continuous()
              ? (this.previousPhase === W.au.CREATING ||
                  this.previousPhase === W.au.CREATING_NEXT_POINT) &&
                this.setPhase(W.au.CREATING_NEXT_POINT)
              : this.previousPhase === W.au.CREATING
              ? this.setPhase(W.au.CREATING_NEXT_POINT)
              : this.previousPhase === W.au.CREATING_NEXT_POINT &&
                this.setPhase(W.au.CREATING))
        }
      }
      MeasurementCreatorMobile.longPressCreateThreshold = 500
      class MeasurementCreatorDesktop extends MeasurementCreator {
        constructor(e, t, i, s, n, r, o, a, h, l, d) {
          super(e, t, s, n, r, o, a, h, d),
            (this.continuous = l),
            (this.onCreate = (e) => {
              const t = this.previousPoint.distanceTo(e.point) > re.yV
              if (t || 2 !== this.currentLinePoints) {
                if (this.getPhase() === W.au.CREATING)
                  return (
                    this.createNewLine(e),
                    this.addPointToLine(e),
                    void this.setPhase(W.au.CREATING_NEXT_POINT)
                  )
                t &&
                  this.getPhase() === W.au.CREATING_NEXT_POINT &&
                  (this.continuous()
                    ? (this.updateLastPoint(e), this.addPointToLine(e))
                    : this.finishLine(e))
              } else {
                const t = {
                    origin: e.point.addScaledVector(e.normal, 0.05),
                    normal: e.normal
                  },
                  i = this.pointer.getMeshIntersection(t)
                if (i)
                  if (this.continuous()) {
                    this.points.pop()
                    const e = new ConstrainedHit(i, Le.l1.Free)
                    this.addPointToLine(e),
                      this.addPointToLine(e),
                      this.setPhase(W.au.CREATING_NEXT_POINT)
                  } else this.finishLine(new ConstrainedHit(i, Le.l1.Free))
              }
            }),
            (this.onMouseMove = () => {
              if (this.getPhase() === W.au.CREATING_NEXT_POINT) {
                const e = this.getIntersection()
                e && this.updateLastPoint(e)
              }
            }),
            (this.onMouseClick = (e) => {
              if (e.button !== Ne.MP.PRIMARY || this.getPhase() === W.au.IDLE)
                return
              const t = this.getIntersection()
              t && this.onCreate(t)
            }),
            this.inputSubscriptions.push(
              i(Ve.mE, this.onMouseMove),
              i(ae.R, this.onMouseClick)
            ),
            this.cancelSubs()
        }
        start() {
          super.start()
        }
        stop() {
          this.getPhase() === W.au.CREATING_NEXT_POINT &&
            (this.points.pop(),
            this.currentLinePoints < 3 && this.points.pop()),
            super.stop()
        }
        finishLine(e) {
          this.points.pop(),
            this.addPointToLine(e),
            this.setPhase(W.au.CREATING),
            this.onDone()
        }
      }
      var Qe = i(42530),
        _e = i(75256),
        He = i(88727),
        je = i(88216),
        qe = i(81507),
        Ze = i(60771),
        Xe = i(21244)
      class SnappableAxisUpdater {
        constructor(e, t, i, s, n) {
          ;(this.pointer = e),
            (this.mobile = t),
            (this.getPhase = i),
            (this.scene = s),
            (this.getLayer = n),
            (this.subscriptions = []),
            (this.editing = !1),
            (this.axisLines = []),
            (this.axisAlignmentHelper = new f.Object3D()),
            (this.updateSnapping = (e) => {
              if (
                (this.axisLines.length > 0 &&
                  (this.pointer.removeSnapFeatures(this, Se.AxisAny),
                  (this.axisLines.length = 0)),
                e)
              ) {
                this.axisAlignmentHelper.position.copy(e.point)
                const t = (0, se.J2)(
                  this.axisAlignmentHelper,
                  e.point,
                  e.normal
                )
                this.axisAlignmentHelper.updateMatrixWorld(!0)
                const i = this.axisAlignmentHelper.matrixWorld,
                  s = 100,
                  n = (e, t, i, n) => {
                    const r = new SnapAxisLine3(
                      e.clone().multiplyScalar(s),
                      t.clone().multiplyScalar(s),
                      n
                    )
                    return r.applyMatrix4(i), r
                  },
                  r = new f.Matrix4().copyPosition(i)
                this.axisLines.push(n(oe.f.UP, oe.f.DOWN, r, Se.AxisY)),
                  t ||
                    this.axisLines.push(
                      n(oe.f.FORWARD, oe.f.BACK, i, Se.AxisY),
                      n(oe.f.UP, oe.f.DOWN, i, Se.AxisX),
                      n(oe.f.LEFT, oe.f.RIGHT, i, Se.AxisZ)
                    ),
                  this.axisLines.length > 0 &&
                    this.pointer.addSnapFeatures(
                      this,
                      Se.AxisAny,
                      this.axisLines
                    )
              }
            })
        }
        init() {}
        dispose() {}
        activate() {
          this.subscriptions.push(
            this.pointer.onOriginChanged(this.updateSnapping, !0)
          ),
            (this.axisLineRenderer = new AxisLineRenderer(
              this.scene,
              this.getLayer('cursor-mesh')
            ))
        }
        deactivate() {
          this.subscriptions.forEach((e) => e.cancel()),
            (this.subscriptions.length = 0),
            this.pointer.removeSnapFeatures(this, Se.AxisAny),
            this.axisLineRenderer.dispose(),
            (this.axisLineRenderer = null)
        }
        beforeRender() {
          const e = this.getPhase(),
            t = this.mobile ? !!W.Pj.mobile[e] : !!W.Pj.desktop[e]
          t !== this.editing &&
            ((this.editing = t), this.axisLineRenderer.clearLines())
        }
        render() {
          this.editing &&
            this.axisLineRenderer.render(
              this.pointer.lastIntersection,
              this.axisLines
            )
        }
      }
      class AxisLineRenderer {
        constructor(e, t) {
          ;(this.scene = e),
            (this.layer = t),
            (this.offsetFromMesh = 0.0075),
            (this.featureColors = {
              [Se.AxisX]: ie.x,
              [Se.AxisZ]: ie.z,
              [Se.AxisY]: ie.y
            }),
            (this.axesVisibleInConstraints = {
              [Le.l1.EdgesAndPlanarAxes]: !0,
              [Le.l1.Axes]: !0,
              [Le.l1.PlanarAxes]: !0
            }),
            (this.linesActive = []),
            (this.linesFree = []),
            (this.axesVisible = []),
            (this.axisMat = new f.LineBasicMaterial({
              color: 4095,
              linewidth: 1,
              opacity: 0.75,
              transparent: !0,
              depthWrite: !1,
              depthTest: !0
            })),
            (this.render = (e, t) => {
              if (
                e &&
                this.axesVisibleInConstraints[e.constraint] &&
                t.length > 0
              ) {
                if (t.length !== this.axesVisible.length) this.clearLines()
                else {
                  this.axesVisible.every((e, i) => e.equals(t[i])) ||
                    this.clearLines()
                }
                if (this.container.parent !== this.scene.scene) {
                  for (const e of t) {
                    const t = this.getMesh(e)
                    t.material.color.setHex(this.featureColors[e.featureType]),
                      this.container.add(t),
                      this.linesActive.push(t)
                  }
                  ;(this.axesVisible = t.map((e) => e)),
                    this.scene.addChild(a.a.Root, this.container),
                    this.container.position
                      .copy(e.normal)
                      .multiplyScalar(this.offsetFromMesh),
                    this.container.updateMatrixWorld(!0)
                }
              } else this.clearLines()
            }),
            (this.clearLines = () => {
              if (0 !== this.linesActive.length) {
                for (; this.linesActive.length > 0; ) {
                  const e = this.linesActive.pop()
                  e && (this.container.remove(e), this.linesFree.push(e))
                }
                this.scene.removeChild(a.a.Root, this.container)
              }
            }),
            (this.container = new f.Object3D())
        }
        getMesh(e) {
          let t = this.linesFree.pop()
          return (
            t
              ? t.geometry.setFromPoints([e.start, e.end])
              : ((t = new LineMesh(e, this.axisMat.clone())),
                (t.layers.mask = this.layer.mask)),
            t
          )
        }
        dispose() {
          for (this.clearLines(); this.linesFree.length > 0; ) {
            const e = this.linesFree.pop()
            e &&
              (this.container.remove(e),
              e.geometry.dispose(),
              e.material.dispose())
          }
          ;(this.linesActive = []),
            (this.linesFree = []),
            (this.container = null)
        }
      }
      class LineMesh extends f.Line {
        constructor(e, t) {
          super(void 0, t),
            (this.material = t),
            (this.geometry = new f.BufferGeometry().setFromPoints([
              e.start,
              e.end
            ]))
        }
      }
      var We,
        Ye = i(29539),
        $e = i(48602),
        Ke = i(26587),
        Je = i(38420),
        et = i(50988),
        tt = i(94474),
        it = i(71918),
        st = i(37946)
      !(function (e) {
        ;(e.LINETYPE_2D = 'linetype_2D'), (e.LINETYPE_3D = 'linetype_3D')
      })(We || (We = {}))
      const nt = {
          [T.T.FloorplanOnly]: We.LINETYPE_2D,
          [T.T.ThreeD]: We.LINETYPE_3D
        },
        rt = {
          [We.LINETYPE_2D]: T.T.FloorplanOnly,
          [We.LINETYPE_3D]: T.T.ThreeD
        }
      class MdsMeasurementPointGroupSerializer {
        serialize(e) {
          if (!e) return null
          const t = [],
            { text: i, visible: s, type: n, floorId: r, roomId: o } = e.info
          for (const i of e) {
            const e = { position: Te.ep.toVisionVector(i) }
            r && (e.floorId = r), o && (e.roomId = o), t.push(e)
          }
          const a = {
            enabled: s,
            label: i,
            version: '3.2',
            lineType: nt[n] || We.LINETYPE_3D,
            points: t
          }
          return this.validate(a) ? a : null
        }
        validate(e) {
          return !!e && !(e.points.length < 2)
        }
      }
      var ot = i(31879)
      const at = new w.Z('mds-measurement-serializer')
      class MdsMeasurementPointGroupDeserializer {
        constructor() {
          ;(this.points = (0, _e.C)([])), (this.grouper = new $.h(this.points))
        }
        deserialize(e) {
          if (!e || !Array.isArray(e)) return at.debug('No contents', e), null
          this.grouper.reset()
          for (const t of e)
            if (this.validate(t)) {
              const e = t.lineType || We.LINETYPE_3D,
                i = rt[e],
                s = this.getModelContextFromPoint(t.points[0]),
                n = Object.assign(
                  Object.assign(
                    {
                      sid: t.id,
                      text: t.label || '',
                      visible: t.enabled,
                      type: i
                    },
                    s
                  ),
                  {
                    created: (0, ot.p)(t.created),
                    modified: (0, ot.p)(t.modified)
                  }
                )
              this.grouper.startGroup(n),
                t.points.forEach((e) =>
                  this.grouper.push(Te.ep.fromVisionVector(e.position))
                )
            } else at.debug('Deserialized invalid Measurement data from MDS', t)
          return 0 === this.grouper.length ? null : this.grouper
        }
        validate(e) {
          if (!e || 'object' != typeof e) return !1
          const t = ['id', 'points'].every((t) => t in e),
            i = e.points && Array.isArray(e.points) && e.points.length > 0,
            s = t && i
          return (
            s ||
              at.debug('Invalid MDS.MeasurementPath:', {
                hasRequiredFields: t,
                hasPoints: i,
                data: e
              }),
            s
          )
        }
        getModelContextFromPoint(e) {
          return {
            floorId: e.floor && e.floor.id ? e.floor.id : '',
            roomId: e.room && e.room.id ? e.room.id : ''
          }
        }
      }
      var ht = i(92540),
        lt = i(53204),
        dt = i(93863)
      class MdsMeasurementModeStore extends tt.u {
        constructor() {
          super(...arguments),
            (this.serializer = new MdsMeasurementPointGroupSerializer()),
            (this.deserializer = new MdsMeasurementPointGroupDeserializer()),
            (this.prefetchKey = 'data.model.measurementPaths')
        }
        async read(e) {
          const { includeDisabled: t = !1 } = this.config,
            i = { modelId: this.getViewId(), includeDisabled: t }
          return this.query(st.GetMeasurements, i, e).then((e) => {
            var t, i
            if (!ht.w.isOk(e))
              throw new dt.Zb('MdsMeasurementModeStore.read failed')
            return this.deserializer.deserialize(
              null ===
                (i =
                  null === (t = null == e ? void 0 : e.data) || void 0 === t
                    ? void 0
                    : t.model) || void 0 === i
                ? void 0
                : i.measurementPaths
            )
          })
        }
        async create(e) {
          const t = this.getViewId(),
            i = this.serializer.serialize(e)
          if (!i) throw new Error('Could not create Measurement')
          return this.mutate(st.AddMeasurement, { modelId: t, data: i }).then(
            (e) => (0, it.qw)(e, 'data.addMeasurementPath.id')
          )
        }
        async update(e) {
          if (!e || 0 === e.length) return Promise.resolve()
          const t = this.getViewId()
          let i = ''
          const s = {}
          s.modelId = t
          let n = ''
          for (const t of e) {
            const e = t.info.sid,
              r = this.serializer.serialize(t)
            if (!r) throw new Error('Could not update Measurement')
            ;(s[`data${e}`] = r),
              (i += `, $data${e}: MeasurementPathPatch!`),
              (n += `patch${e}: patchMeasurementPath(modelId: $modelId, pathId: "${e}", patch: $data${e}) {\n        id\n      }`)
          }
          const r = lt.Ps`
      mutation PatchMeasurements($modelId: ID! ${i}) {
        ${n}
      }
    `
          return this.mutate(r, s).then(() => {})
        }
        async delete(...e) {
          if (!e || 0 === e.length) return
          const t = this.getViewId()
          let i = ''
          for (const t of e)
            i += `delete${t}: deleteMeasurementPath(modelId: $modelId, pathId: "${t}")`
          const s = lt.Ps`
      mutation DeleteMeasurements($modelId: ID!) {
        ${i}
      }
    `
          return this.mutate(s, { modelId: t }).then(() => {})
        }
      }
      var ct = i(86488),
        ut = i(71194),
        pt = i(92532),
        gt = i(79553),
        mt = i(76236),
        wt = i(93673)
      const ft = new w.Z('measurement-mode')
      class MeasurementModeModule extends s.Y {
        constructor() {
          super(...arguments),
            (this.name = 'measurement-mode'),
            (this.longPressStart = Date.now()),
            (this.threshold = 800),
            (this.lineSidToPointMap = {}),
            (this.mobile = !1),
            (this.cameraAndDragBlocked = !1),
            (this.blockNavigation = () => !1),
            (this.store = null),
            (this.trashEnabled = !1),
            (this.changeCursor = (e) => {
              this.engine.commandBinder.issueCommand(new d.u(e))
            }),
            (this.replaceContents = (e) => {
              this.lineDerivedDataFactory.clear(),
                e ? this.pointGroups.copy(e) : this.pointGroups.reset()
            }),
            (this.onEdit = (e) => {
              const t = this.data.getGroupInfo(e),
                i = (t && t.info.sid) || null
              this.data.editingGroupId !== i &&
                ((this.data.editingGroupId = i),
                this.colliders.setEditingGroup(e))
            }),
            (this.onEditEnd = () => {
              if (this.data.editingGroupId) {
                const e = this.pointGroups.getGroupById(
                  this.data.editingGroupId
                )
                e &&
                  (this.mutationRecord.updated.add(e.info.sid),
                  this.save(),
                  this.engine.broadcast(
                    new Xe.av(this.buildAnalyticsMessageFromGroup(e))
                  ))
              }
              ;(this.data.editingGroupId = null),
                this.colliders.setEditingGroup(void 0)
            }),
            (this.onCreatorAddNewLine = (e) => {
              ft.debug('onCreatorAddNewLine', e),
                (this.data.creatingGroupId = e)
            }),
            (this.onCreatorAddPoint = () => {
              if (this.data.creatingGroupId) {
                ft.debug('onCreatorAddNewSegment', this.data.creatingGroupId)
                const e = this.pointGroups.getGroupById(
                  this.data.creatingGroupId
                )
                if (e && e.count > 1 && e.length > 0) {
                  const t = this.buildAnalyticsMessageFromGroup(e)
                  this.engine.broadcast(
                    new Xe.rf(
                      Object.assign(Object.assign({}, t), {
                        startPosition: this.pointGroups.get(e.startIndex),
                        endPosition: this.pointGroups.get(e.endIndex)
                      })
                    )
                  )
                }
              }
            }),
            (this.onCreatorStop = () => {
              if (this.data.creatingGroupId) {
                const e = this.pointGroups.getGroupById(
                  this.data.creatingGroupId
                )
                e &&
                  (e.count > 1 && e.hasLength()
                    ? (this.engine.broadcast(
                        new Xe.u6(
                          Object.assign(
                            {},
                            this.buildAnalyticsMessageFromGroup(e)
                          )
                        )
                      ),
                      this.mutationRecord.added.add(e.info.sid),
                      this.save())
                    : this.engine.broadcast(new Xe.ff()))
              }
              this.data.creatingGroupId = null
            }),
            (this.onToggleMeasurementMode = async (e, t) => {
              this.toggleMeasuringMode(e),
                await this.engine.commandBinder.issueCommand(new Z.I(e && t))
            }),
            (this.onViewmodeChange = () => {
              this.getPhase() !== W.au.CLOSED && this.stopMeasuring()
            }),
            (this.onSweepChange = () => {
              const e = this.getPhase()
              e !== W.au.CREATING &&
                e !== W.au.CREATING_NEXT_POINT &&
                this.setSelected(-1)
            }),
            (this.initStorageOnApplicationChange = () => {
              this.config.readonly =
                this.applicationData.application !== z.Mx.WORKSHOP
              const e =
                !this.config.readonly ||
                this.playerOptions.options.measurements_saved
              if (
                (this.data.modeActive() &&
                  this.engine.commandBinder.issueCommand(new V.O(!1)),
                e && this.store)
              ) {
                const e = this.store
                ;(this.store = null),
                  e.read().then((t) => {
                    this.replaceContents(null == t ? void 0 : t.groups()),
                      (this.store = e)
                  })
              }
              this.configureTrash()
            }),
            (this.getPhase = () => this.data.phase),
            (this.toggleCameraMovement = (e) => {
              e || this.cameraAndDragBlocked
                ? e &&
                  this.cameraAndDragBlocked &&
                  (this.dragInterceptor.cancel(),
                  this.navigation.removeNavigationRule(this.blockNavigation),
                  (this.cameraAndDragBlocked = !1))
                : (this.dragInterceptor.renew(),
                  this.navigation.addNavigationRule(this.blockNavigation),
                  (this.cameraAndDragBlocked = !0))
            }),
            (this.getConstraint = () =>
              this.settings.tryGetProperty(O.F.MeasurementSnapping, !1)
                ? this.viewmodeData.isFloorplan()
                  ? re.xh.floorplan
                  : this.constraint
                : re.xh.disabled),
            (this.getSelected = () => this.data.selectedGroupIndex),
            (this.setSelected = (e) => {
              this.data.selectedGroupIndex !== e &&
                this.data.setSelectedGroupIndex(e)
            }),
            (this.setSelectedById = async (e) => {
              if (null === e) this.setSelected(-1)
              else {
                const t = this.pointGroups.getGroupById(e)
                t && this.setSelected(t.index)
              }
            }),
            (this.deleteSelectedMeasurement = () => {
              ;-1 !== this.data.selectedGroupIndex &&
                (this.deleteMeasurement(this.data.selectedGroupIndex),
                this.setSelected(-1),
                this.changePhase(W.au.IDLE),
                this.mobile ||
                  (this.navigation.removeNavigationRule(this.blockNavigation),
                  this.engine.commandBinder.issueCommand(new d.u(l.C.DEFAULT))))
            }),
            (this.deleteMeasurement = (e, t = !1) => {
              const i = this.buildAnalyticsMessage(e)
              i &&
                this.engine.broadcast(
                  new Xe.$Z(
                    Object.assign(Object.assign({}, i), {
                      count: this.pointGroups.groupCount - 1
                    })
                  )
                )
              const s = this.pointGroups.getGroup(e)
              s &&
                (this.pointGroups.removeGroup(e),
                s.info.sid !== this.data.creatingGroupId &&
                  (this.mutationRecord.removed.add(s.info.sid),
                  t || this.save()))
            }),
            (this.deleteMeasurementBySids = async (e) => {
              const t = e.sids
              for (const i of t) {
                const t = this.pointGroups.getGroupById(i)
                if (!t)
                  throw (
                    (ft.error(
                      'Measurement delete failed',
                      Object.assign({}, e)
                    ),
                    Error('Measurement delete failed, not found'))
                  )
                this.deleteMeasurement(t.index, !0)
              }
              this.save()
            }),
            (this.onToggleContinuous = () => {
              this.stopMeasuring()
            }),
            (this.changePhase = (e) => {
              this.getPhase() !== e &&
                (ft.debug(
                  `Phase Change: ${W.au[this.getPhase()]} -> ${W.au[e]}`
                ),
                (this.previousPhase = this.getPhase()),
                this.data.setPhase(e))
            }),
            (this.restorePreviousPhase = () => {
              this.changePhase(this.previousPhase)
            }),
            (this.onPhaseChange = (e) => {
              if (
                (this.intersectionVisualizer.setMeasuringPhase(e),
                this.previousPhase !== e)
              )
                switch (e) {
                  case W.au.CLOSED:
                  case W.au.IDLE:
                    this.engine.broadcast(new X.ps(!0))
                    break
                  case W.au.EDITING:
                  case W.au.CREATING:
                  case W.au.POINT_PLACED:
                  case W.au.CREATING_NEXT_POINT:
                  case W.au.CONFIRMING_POINT:
                    this.engine.broadcast(new X.ps(!1))
                }
            }),
            (this.buildAnalyticsMessage = (e) => {
              const t = this.pointGroups.getGroup(e)
              return t && t.hasLength()
                ? this.buildAnalyticsMessageFromGroup(t)
                : null
            }),
            (this.buildAnalyticsMessageFromGroup = (e) => {
              const t = this.viewmodeData.isFloorplan()
                ? T.T[T.T.FloorplanOnly]
                : T.T[T.T.ThreeD]
              return Object.assign(
                Object.assign(
                  {
                    sid: e.info && e.info.sid ? e.info.sid : e.describe(),
                    totalLength: e ? e.length : 0,
                    segments: e ? e.count : 0,
                    temporary: !e.info || e.info.sid === e.describe(),
                    viewmode: this.viewmodeData.currentMode,
                    floorId: e.info.floorId,
                    continuous: this.settings.tryGetProperty(
                      O.F.MeasurementContinuousLines,
                      !1
                    )
                  },
                  this.getAnalyticsForConstraints()
                ),
                { type: t }
              )
            }),
            (this.getAnalyticsForConstraints = () => {
              const e = this.pointer.lastIntersection
              if (e) {
                const t = e.featureType,
                  i = e.constraint
                return {
                  featureType: void 0 !== t ? Se[t] : 'None',
                  constraint: Le.l1[i]
                }
              }
              return null
            }),
            (this.toggleMeasuringMode = (e) => {
              ft.debug('toggleMeasuringMode', e)
              e !== (this.getPhase() !== W.au.CLOSED) &&
                (e
                  ? (this.engine.toggleRendering(this, !0),
                    this.changePhase(W.au.IDLE),
                    this.editor.activate(),
                    this.lineStyler.activate(),
                    this.colliders.activate(),
                    this.renderer.activate(),
                    this.textRenderer.activate(),
                    this.scene.addChild(a.a.Root, this.textRenderer.container),
                    this.engine.broadcast(
                      new Xe.$n(
                        !0,
                        this.viewmodeData.currentMode,
                        this.pointGroups.groupCount
                      )
                    ),
                    this.pointer.preload())
                  : (this.engine.toggleRendering(this, !1),
                    this.stopMeasuring(),
                    this.changePhase(W.au.CLOSED),
                    this.toggleCameraMovement(!0),
                    this.editor.deactivate(),
                    this.lineStyler.deactivate(),
                    this.colliders.deactivate(),
                    this.renderer.deactivate(),
                    this.textRenderer.deactivate(),
                    this.scene.removeChild(
                      a.a.Root,
                      this.textRenderer.container
                    ),
                    this.engine.broadcast(
                      new Xe.$n(
                        !1,
                        this.viewmodeData.currentMode,
                        this.pointGroups.groupCount
                      )
                    )))
            }),
            (this.startMeasuring = () => {
              this.mobile ||
                (this.navigation.addNavigationRule(this.blockNavigation),
                this.engine.commandBinder.issueCommand(new d.u(l.C.XHAIR))),
                this.creator.start()
            }),
            (this.stopMeasuring = () => {
              const e = this.isMeasurementComplete(this.data.selectedGroupIndex)
              this.isCreating() && !e && this.deleteSelectedMeasurement(),
                this.creator.stop(),
                this.mobile ||
                  (this.navigation.removeNavigationRule(this.blockNavigation),
                  this.engine.commandBinder.issueCommand(new d.u(l.C.DEFAULT)))
            }),
            (this.setupIntersectionVisuals = (e, t, i, s, n, r, o, a) => {
              t.addVisibilityRule(() => {
                const e = this.getPhase()
                return !(
                  (!r && e === W.au.CREATING) ||
                  e === W.au.CONFIRMING_POINT ||
                  e === W.au.CREATING_NEXT_POINT ||
                  e === W.au.EDITING
                )
              })
              const h = { cameraData: s, playerCamera: i.camera, scene: i }
              return new IntersectionVisualizer(
                r,
                n,
                h,
                e,
                o,
                this.engine.commandBinder.issueCommand,
                a.isFloorplan
              )
            }),
            (this.mutationRecord = {
              [ut.KI.added]: new Set(),
              [ut.KI.updated]: new Set(),
              [ut.KI.removed]: new Set()
            }),
            (this.clearMutationRecord = () => {
              for (const e of Object.values(this.mutationRecord)) e.clear()
            }),
            (this.renameMeasurement = async (e) => {
              const t = this.pointGroups.getGroupById(e.sid)
              if (!t)
                throw (
                  (ft.error('Measurement rename failed', Object.assign({}, e)),
                  Error('Measurement rename failed, not found'))
                )
              const i = void 0 !== e.text && e.text.length <= 24
              if (!t || !i)
                throw (
                  (ft.error(
                    'Measurement text invalid, text must be between 0 and 24 charachters in length.',
                    Object.assign({}, e)
                  ),
                  new Error('Measurement text invalid'))
                )
              {
                const i = '' === t.info.text && e.text.length > 0,
                  s = !i && t.info.text !== e.text
                this.pointGroups.updateGroupInfo(
                  t.index,
                  Object.assign(Object.assign({}, t.info), { text: e.text })
                ),
                  this.mutationRecord.updated.add(t.info.sid),
                  this.save(),
                  i && this.engine.broadcast(new Xe.ty(e.sid, e.text)),
                  s &&
                    this.engine.broadcast(new Xe.mM(e.sid, t.info.text, e.text))
              }
            }),
            (this.onChangeVisibility = async (e) => {
              for (const t of e.sids) {
                const i = this.pointGroups.getGroupById(t)
                if (!i)
                  throw (
                    (ft.error(
                      'Measurement visibility toggle failed',
                      Object.assign(Object.assign({}, e), { group: i })
                    ),
                    new Error(
                      'Measurement visibility toggle failed, not found'
                    ))
                  )
                {
                  this.pointGroups.updateGroupInfo(
                    i.index,
                    Object.assign(Object.assign({}, i.info), {
                      visible: e.visible
                    })
                  ),
                    this.mutationRecord.updated.add(i.info.sid)
                  const t = this.buildAnalyticsMessage(i.index)
                  t && this.engine.broadcast(new Xe.av(t))
                }
              }
              this.save()
            })
        }
        async init(e, t) {
          ;(this.config = e), (this.mobile = (0, Ze.tq)()), (this.engine = t)
          const [i, s, a, l, d, u, w, f, v, T] = await Promise.all([
            t.getModuleBySymbol(n.y.WEBGL_RENDERER),
            t.getModule(r.default),
            t.getModuleBySymbol(n.y.INPUT),
            t.getModule(h.default),
            t.getModule(o.default),
            t.market.waitForData(g.c),
            t.market.waitForData(p.M_),
            t.market.waitForData(m.O),
            t.market.waitForData(G.Z),
            t.market.waitForData(ct.Z)
          ])
          ;(this.settings = await t.market.waitForData(A.e)),
            (this.playerOptions = await t.market.waitForData(N.af)),
            (this.storageData = await t.market.waitForData($e.Q)),
            (this.scene = i.getScene()),
            (this.viewmodeData = f),
            (this.floorsViewData = u),
            (this.roomData = T),
            (this.input = a),
            (this.navigation = await t.getModule(Ye.default)),
            (this.meshQueryModule = await t.getModuleBySymbol(n.y.MESH_QUERY))
          const y = await t.getModule(Ke.F)
          this.lineDerivedDataFactory = new LineDerivedDataFactory(
            w,
            f,
            u,
            () => !!v.currentSweep && v.isSweepAligned(v.currentSweep),
            () => this.settings.tryGetProperty(O.F.UnitType, S.M.IMPERIAL),
            () => !0
          )
          const P = t.claimRenderLayer(this.name)
          ;(this.data = new Y.X()), t.market.register(this, Y.X, this.data)
          const D = (0, _e.C)([])
          this.pointGroups = new $.h(D)
          const b = (e, t, i = !1) => te(D, e).createSubscription(t, i)
          ;(this.dataSubscription = b(
            k.ALL,
            () => {
              this.data.repopulate(this.pointGroups.groups()),
                this.data.commit()
            },
            !0
          )),
            (this.applicationData = await t.market.waitForData(z.pu)),
            this.config.storageProvider === Je.Xq.MDS &&
              ((this.store = this.configureStorage()),
              this.initStorageOnApplicationChange()),
            (this.constraint = this.mobile ? re.xh.mobile : re.xh.desktop),
            (this.pointer = new SnappablePointer(
              d,
              this.getConstraint,
              this.mobile,
              this.floorsViewData,
              this.viewmodeData
            ))
          const M = new SnappablePointUpdater(
            this.pointGroups,
            b,
            this.pointer,
            () => {
              const e = this.settings.tryGetProperty(
                  O.F.MeasurementContinuousLines,
                  !1
                ),
                t =
                  this.getPhase() === W.au.CREATING ||
                  this.getPhase() === W.au.CREATING_NEXT_POINT ||
                  (this.previousPhase === W.au.CREATING_NEXT_POINT &&
                    this.getPhase() === W.au.EDITING)
              return e && this.mobile && t
            }
          )
          t.addComponent(this, M)
          const x = new SnappableAxisUpdater(
            this.pointer,
            this.mobile,
            this.getPhase,
            this.scene,
            t.getRenderLayer
          )
          t.addComponent(this, x), (this.creator = this.instantiateCreator(w))
          const I = (e, t, i) => {
            const s = this.pointGroups.getGroup(e),
              n = s.describe(i)
            this.lineSidToPointMap[n] = i
            const r = this.lineDerivedDataFactory.get(n)
            return this.lineDerivedDataFactory.make(
              n,
              () => ({
                start_position: this.pointGroups.get(t),
                end_position: this.pointGroups.get(i),
                visible: s.info.visible,
                floorId: s.info.floorId,
                roomId: s.info.roomId,
                type: s.info.type,
                text: this.pointGroups.isStartIndex(t) ? s.info.text : ''
              }),
              r
            )
          }
          ;(this.renderer = new MeasurementLineRenderer(
            this.pointGroups,
            b,
            w,
            l,
            P,
            t.claimRenderLayer('measure-lines'),
            this.getSelected,
            I
          )),
            await t.addComponent(this, this.renderer)
          const R = new Qe.u({
            color: 'black',
            background: !0,
            backgroundColor: '#ffffff',
            backgroundColliderType: MeasurementLabelBackgroundMesh
          })
          ;(this.textRenderer = new MeasurementLabelRenderer(
            this.pointGroups,
            a,
            this.mobile,
            b,
            w,
            P,
            ve.z.labels,
            R,
            I,
            this.changeCursor,
            this.getPhase,
            this.setSelected
          )),
            await t.addComponent(this, this.textRenderer),
            this.textRenderer.deactivate(),
            (this.editor = new MeasurementJointEditor(
              this.pointGroups,
              a,
              this.pointer,
              this.getPhase,
              this.onEdit,
              this.onEditEnd
            )),
            (this.colliders = new MeasurementInput(
              this.pointGroups,
              this.input,
              w,
              this.mobile,
              this.changeCursor,
              this.getPhase,
              this.changePhase,
              this.restorePreviousPhase,
              this.setSelected,
              this.getSelected,
              this.onEdit,
              this.onEditEnd
            )),
            (this.lineStyler = new MeasurementLineStyler(
              this.renderer.lines,
              this.renderer.getLinesForPoint,
              this.renderer.dottedMaterial,
              b,
              this.input,
              this.getPhase,
              this.getSelected
            ))
          const [C] = await Promise.all([t.getModule(c.default)])
          ;(this.intersectionVisualizer = this.setupIntersectionVisuals(
            s,
            C,
            this.scene,
            w,
            this.pointer,
            this.mobile,
            t.getRenderLayer,
            this.viewmodeData
          )),
            t.addComponent(this, this.intersectionVisualizer),
            (this.dragInterceptor = this.input.registerPriorityHandler(
              Ae._t,
              De.S,
              () => !0
            )),
            this.dragInterceptor.cancel(),
            this.mobile || this.bindings.push(...this.hotkeys()),
            this.bindings.push(
              this.applicationData.onPropertyChanged(
                'application',
                this.initStorageOnApplicationChange
              ),
              f.makeModeChangeSubscription(this.onViewmodeChange),
              v.makeSweepChangeSubscription(this.onSweepChange),
              t.commandBinder.addBinding(V.O, async (e) =>
                this.onToggleMeasurementMode(e.on, e.dimWhileActive)
              ),
              t.commandBinder.addBinding(U.c, async () =>
                this.startMeasuring()
              ),
              t.commandBinder.addBinding(B.v, async (e) =>
                this.setSelected(e.index)
              ),
              t.commandBinder.addBinding(Q.B, async () => this.stopMeasuring()),
              t.commandBinder.addBinding(_.Ev, async () =>
                this.deleteSelectedMeasurement()
              ),
              t.commandBinder.addBinding(_.Tn, async (e) =>
                this.deleteMeasurement(e.index)
              ),
              t.commandBinder.addBinding(B.t, async (e) =>
                this.setSelectedById(e.sid)
              ),
              t.commandBinder.addBinding(H.W, this.onChangeVisibility),
              t.commandBinder.addBinding(j.R, this.renameMeasurement),
              t.commandBinder.addBinding(_.JM, this.deleteMeasurementBySids),
              t.commandBinder.addBinding(q.d, async (e) => {
                var t
                return this.replaceContents(
                  null === (t = e.points) || void 0 === t ? void 0 : t.groups()
                )
              }),
              this.dataSubscription,
              this.settings.onPropertyChanged(
                O.F.MeasurementContinuousLines,
                () => this.onToggleContinuous()
              ),
              y.onSave(() => this.saveDiff(), { dataType: Je.g.MEASUREMENTS }),
              this.storageData.onPropertyChanged('currentViewId', () =>
                this.updateSettings()
              ),
              this.data.onPhaseChanged(this.onPhaseChange)
            ),
            t.toggleRendering(this, !1),
            this.updateSettings(),
            this.registerDebugSettings()
        }
        isCreating() {
          const e = this.getPhase()
          return e === W.au.CREATING || e === W.au.CREATING_NEXT_POINT
        }
        setConstraintStyle(e) {
          ft.debug('setConstraintStyle:', Le.l1[e]), (this.constraint = e)
        }
        isMeasurementComplete(e) {
          if (-1 === e || !this.isCreating()) return !0
          const t = this.getPhase(),
            i = this.pointGroups.getGroup(e)
          return this.settings.tryGetProperty(
            O.F.MeasurementContinuousLines,
            !1
          )
            ? i.count > 2 && t === W.au.CREATING_NEXT_POINT
            : i.count >= 2 && t === W.au.CREATING
        }
        hotkeys() {
          return [
            this.input.registerHandler(He.e, (e) => {
              if (e.state === je.M.PRESSED)
                switch (e.key) {
                  case qe.R.ESCAPE:
                    this.getPhase() === W.au.CONFIRMING_POINT
                      ? (this.creator.stop(),
                        this.creator.start(),
                        this.changePhase(W.au.CREATING))
                      : this.isCreating()
                      ? this.stopMeasuring()
                      : this.applicationData.application !== z.Mx.WORKSHOP &&
                        this.getPhase() !== W.au.CLOSED &&
                        this.engine.commandBinder.issueCommand(
                          new pt.tT(gt.w1.MEASUREMENTS, !1)
                        )
                    break
                  case qe.R.BACKSPACE:
                  case qe.R.DELETE:
                    this.getPhase() !== W.au.CLOSED &&
                      this.getPhase() !== W.au.EDITING &&
                      this.deleteSelectedMeasurement()
                    break
                  case qe.R.RETURN:
                    const e = this.pointGroups.groupCount - 1
                    this.isMeasurementComplete(e) && this.stopMeasuring()
                }
            }),
            this.input.registerHandler(He.e, (e) => {
              if (e.key === qe.R.SHIFT || e.key === qe.R.ALT) {
                const { altKey: t, shiftKey: i } = e.modifiers,
                  s =
                    i && t
                      ? re.xh.shiftAlt
                      : t
                      ? re.xh.alt
                      : i
                      ? re.xh.shift
                      : re.xh.desktop
                this.setConstraintStyle(s)
              }
            })
          ]
        }
        onUpdate(e) {
          if (this.getPhase() === W.au.CLOSED) return
          const t = this.data.selectedGroupIndex,
            i = this.mobile
              ? W.Ph.mobile[this.getPhase()]
              : W.Ph.desktop[this.getPhase()]
          for (const s in this.lineSidToPointMap) {
            const n = this.lineDerivedDataFactory.get(s)
            if (n) {
              n.opacity.tick(e)
              const r = this.lineSidToPointMap[s],
                o = this.pointGroups.groupFromPointIndex(r),
                a = o === t && n.visible ? 1 : n.opacity.value,
                h = i && !n.labelVisible ? 0 : a
              this.textRenderer.setTextOpacityByPoint(r, h),
                this.renderer.setLineOpacityByPoint(r, a),
                -1 !== o && this.colliders.setGroupVisible(o, a > 0)
            }
          }
          if (this.mobile)
            if (this.getPhase() === W.au.CONFIRMING_POINT) {
              const e = (Date.now() - this.longPressStart) / this.threshold
              e <= 1 && this.data.setPressProgress(e)
            } else if (
              this.getPhase() === W.au.CREATING &&
              0 !== this.data.pressProgress
            ) {
              const e = 0
              this.data.setPressProgress(e)
            }
        }
        dispose(e) {
          this.stopMeasuring(),
            this.engine.commandBinder.issueCommand(new V.O(!1)),
            this.colliders.dispose(),
            this.textRenderer.dispose(),
            this.renderer.dispose(),
            e.disposeRenderLayer(this.name),
            super.dispose(e)
        }
        async save() {
          if (!this.config.readonly)
            return this.engine.commandBinder.issueCommand(
              new et.VQ({ dataTypes: [Je.g.MEASUREMENTS] })
            )
        }
        async saveDiff() {
          if (
            (this.data.repopulate(this.pointGroups.groups()),
            this.data.commit(),
            this.data.notifyDataChanged(),
            this.config.readonly || !this.store)
          )
            return void this.clearMutationRecord()
          const e = this.mutationRecord,
            t = []
          ft.debug(
            'MDS mutation ops:',
            `{\n      added: '${[...e.added.keys()]}',\n      updated: '${[
              ...e.updated.keys()
            ]}',\n      removed: '${[...e.removed.keys()]}',\n    }`
          )
          const i = []
          for (const t of e[ut.KI.removed])
            e[ut.KI.added].has(t) ? e[ut.KI.added].delete(t) : i.push(t),
              e[ut.KI.updated].delete(t)
          const s = this.store.delete(...i)
          t.push(s)
          for (const i of e[ut.KI.added]) {
            const s = this.pointGroups.getGroupById(i)
            if (s) {
              const e = this.store.create(s).then((e) => {
                e &&
                  (ft.debug(
                    `Updating group id for new path: ${s.info.sid} -> ${e}`
                  ),
                  this.pointGroups.updateGroupInfo(
                    s.index,
                    Object.assign(Object.assign({}, s.info), { sid: e })
                  )),
                  this.data.repopulate(this.pointGroups.groups()),
                  this.data.commit(),
                  this.data.notifyDataChanged()
              })
              t.push(e)
            }
            e[ut.KI.updated].delete(i)
          }
          const n = []
          for (const t of e[ut.KI.updated]) {
            const e = this.pointGroups.getGroupById(t)
            e && n.push(e)
          }
          const r = this.store.update(n)
          return t.push(r), this.clearMutationRecord(), Promise.all(t)
        }
        configureStorage() {
          const { readonly: e, storageProvider: t, baseUrl: i } = this.config
          if (t === Je.Xq.MDS) {
            ft.info(`Loading Measurements from ${t}`)
            const s = new MdsMeasurementModeStore({
              readonly: e,
              includeDisabled: !e,
              baseUrl: i
            })
            return (
              this.engine.market.waitForData($e.Q).then((e) => {
                e.setRevertable(Je.g.MEASUREMENTS)
              }),
              s
            )
          }
          return null
        }
        async registerDebugSettings() {
          const e = await this.engine.getModule(u.default)
          e.registerMenuEntry({
            header: 'Measurement Debug',
            setting: 'measure/fp_in_dh',
            initialValue: () => !1,
            onChange: (t) => (
              this.lineDerivedDataFactory.setDollhouseLineStyle(
                t ? T.T.FloorplanOnly : T.T.ThreeD
              ),
              e.updateSetting('measure/fp_in_dh', t)
            )
          })
        }
        updateSettings() {
          const e = this.storageData.getCurrentView(),
            t = (null == e ? void 0 : e.viewType) === Je.XZ.TRUEPLAN,
            i = this.settings.tryGetProperty(re.Ql, !0),
            s = t || i
          this.settings.setProperty(re.Ql, s)
        }
        instantiateCreator(e) {
          let t
          const i = (e) => {
            const t = { floorId: '', roomId: '' }
            return this.meshQueryModule.inferMeshIdsFromPoint(t, e), t
          }
          if (this.mobile) {
            const s = (e, t) => {
                ;(this.longPressStart = e), (this.threshold = t)
              },
              n = (t) => {
                const i = (0, P.q9)(e, t.point)
                this.data.setPointPosition(i.screenPosition)
              }
            t = new MeasurementCreatorMobile(
              this.pointGroups,
              this.setSelected,
              this.input.registerUnfilteredHandler,
              this.pointer,
              this.changePhase,
              s,
              n,
              this.toggleCameraMovement,
              this.getPhase,
              () =>
                this.settings.tryGetProperty(
                  O.F.MeasurementContinuousLines,
                  !1
                ),
              this.viewmodeData.isFloorplan,
              this.floorsViewData.getHighestVisibleFloorId,
              () => this.roomData.selected.value,
              i
            )
          } else
            t = new MeasurementCreatorDesktop(
              this.pointGroups,
              this.setSelected,
              this.input.registerUnfilteredHandler,
              this.pointer,
              this.changePhase,
              this.getPhase,
              this.viewmodeData.isFloorplan,
              this.floorsViewData.getHighestVisibleFloorId,
              () => this.roomData.selected.value,
              () =>
                this.settings.tryGetProperty(
                  O.F.MeasurementContinuousLines,
                  !1
                ),
              i
            )
          return (
            (t.onGroupCreated = this.onCreatorAddNewLine),
            (t.onGroupAddPoint = this.onCreatorAddPoint),
            (t.onEdit = this.onEdit),
            (t.onDone = this.onCreatorStop),
            t
          )
        }
        async configureTrash() {
          const { readonly: e, storageProvider: t } = this.config
          if (this.trashEnabled || e || t !== Je.Xq.MDS) return
          const { commandBinder: i } = this.engine,
            s = Je.g.MEASUREMENTS,
            n = {
              objectType: s,
              create: (e) =>
                new mt.F({
                  label: e.label || 'Measurement',
                  objectId: e.id,
                  objectType: s,
                  created: new Date(),
                  value: e
                }),
              restore: (e) => {}
            }
          this.trashEnabled = !0
          const r = await i.issueCommandWhenBound(new wt.B(n))
          this.bindings.push(r)
        }
      }
      const vt = MeasurementModeModule
    },
    41659: (e, t, i) => {
      'use strict'
      i.d(t, { u: () => SetMeshOverlayCommand })
      var s,
        n,
        r = i(17386)
      !(function (e) {
        ;(e.all = 'all'),
          (e.byFloorId = 'byFloorId'),
          (e.byRoomId = 'byRoomId'),
          (e.byMeshGroup = 'byMeshGroup'),
          (e.byMeshSubGroup = 'byMeshSubGroup')
      })(s || (s = {})),
        (function (e) {
          ;(e.explicit = 'explicit'), (e.random = 'random')
        })(n || (n = {}))
      class SetMeshOverlayCommand extends r.m {
        constructor(e, t) {
          super(),
            (this.id = 'SET_MESH_OVERLAY_COLOR'),
            (this.payload = {
              selectBy: (null == t ? void 0 : t.style) || s.all,
              colorStyle: (null == e ? void 0 : e.style) || n.explicit,
              color: (null == e ? void 0 : e.color) || null,
              alpha: (null == e ? void 0 : e.alpha) || 0.5,
              id: null == t ? void 0 : t.id,
              index: null == t ? void 0 : t.index
            })
        }
      }
      ;(SetMeshOverlayCommand.selectBy = s),
        (SetMeshOverlayCommand.colorBy = n),
        (SetMeshOverlayCommand.COLOR_DIM = { x: 0, y: 0, z: 0, w: 0.3 })
    },
    81638: (e, t, i) => {
      'use strict'
      i.d(t, { I: () => ToggleMeshOverlayColorCommand })
      var s = i(17386)
      class ToggleMeshOverlayColorCommand extends s.m {
        constructor(e) {
          super(),
            (this.id = 'TOGGLE_MESH_OVERLAY_COLOR'),
            (this.payload = { enabled: e })
        }
      }
    },
    96811: (e, t, i) => {
      'use strict'
      i.r(t), i.d(t, { default: () => ScanInfoDataModule })
      var s = i(47724),
        n = i(88512),
        r = i(38420),
        o = i(71918)
      class ScanData {}
      var a = i(23573)
      class ScanCameraInfo extends a.T {
        equals(e) {
          return this.id === e.id
        }
        copy(e) {
          return (
            (this.id = e.id),
            (this.name = e.name),
            (this.vendor = e.vendor),
            (this.model = e.model),
            (this.captureMode = e.captureMode),
            (this.depthCameraType = e.depthCameraType),
            (this.cameraTypes = e.cameraTypes.slice()),
            (this.sensorSerialNumbers = e.sensorSerialNumbers.slice()),
            (this.serialNumber = e.serialNumber),
            (this.mountCalibrationVersion = e.mountCalibrationVersion),
            (this.softwareVersion = e.softwareVersion),
            this
          )
        }
      }
      class ScanInfo extends a.T {
        constructor(e) {
          super(),
            e &&
              (e.id && (this.id = e.id),
              void 0 !== e.index && (this.index = e.index),
              (this.name = e.name || ''),
              (this.created = e.created || ''),
              (this.alignment = e.alignment || ''),
              (this.options = e.options || []),
              (this.camera = e.camera || new ScanCameraInfo()))
        }
        equals(e) {
          return this.id === e.id
        }
        copy(e) {
          return (
            (this.id = e.id),
            (this.index = e.index),
            (this.name = e.name),
            (this.created = e.created),
            (this.alignment = e.alignment),
            (this.options = e.options.slice()),
            (this.camera = new ScanCameraInfo().copy(e.camera)),
            this
          )
        }
      }
      const h = new n.Z('mds-scaninfo-serializer')
      class MdsScanInfoDeserializer {
        deserialize(e) {
          if (!e || !this.validate(e))
            return (
              h.debug('Deserialized invalid ScanInfo data from MDS', e), null
            )
          const t = e,
            i = new ScanInfo()
          ;(i.id = t.id),
            (i.anchorId = (t.anchor && t.anchor.id) || ''),
            (i.index = t.index || -1),
            (i.name = t.name || ''),
            (i.created = t.created || ''),
            (i.alignment = t.alignment || ''),
            (i.url = t.url || ''),
            (i.timeOfDay = t.timeOfDay || ''),
            (i.options = t.options || [])
          const s = t.camera
          return (
            (i.camera = new ScanCameraInfo()),
            (i.camera.id = (s && s.id) || ''),
            (i.camera.name = (s && s.name) || ''),
            (i.camera.vendor = (s && s.vendor) || ''),
            (i.camera.model = (s && s.model) || ''),
            (i.camera.captureMode = (s && s.captureMode) || ''),
            (i.camera.depthCameraType = (s && s.depthCameraType) || ''),
            (i.camera.cameraTypes = (s && s.cameraTypes) || []),
            (i.camera.sensorSerialNumbers = (s && s.sensorSerialNumbers) || []),
            (i.camera.serialNumber = (s && s.serialNumber) || ''),
            (i.camera.mountCalibrationVersion = s
              ? s.mountCalibrationVersion
              : void 0),
            (i.camera.softwareVersion = (s && s.softwareVersion) || ''),
            i
          )
        }
        validate(e) {
          if (!e) return !1
          return ['id'].every((t) => t in e)
        }
      }
      var l = i(94474),
        d = i(80639)
      class MdsScanInfoStore extends l.u {
        constructor() {
          super(...arguments),
            (this.deserializer = new MdsScanInfoDeserializer())
        }
        async fetch() {
          const e = this.getViewId()
          return this.query(
            d.GetScans,
            { modelId: e },
            { fetchPolicy: 'no-cache' }
          ).then((e) => {
            const t = (0, o.qw)(e, 'data.model.assets.scans'),
              i = {},
              s = {}
            for (const e of t) {
              const t = this.deserializer.deserialize(e)
              t && ((i[t.id] = t), t.anchorId && (s[t.anchorId] = t))
            }
            const n = new ScanData()
            return (n.scansById = i), (n.scansByAnchor = s), n
          })
        }
        async read() {
          return this.scans || (this.scans = this.fetch()), this.scans
        }
        async refresh() {
          return (this.scans = this.fetch()), this.scans
        }
      }
      var c = i(46963)
      class EmptyScanInfoStore {
        async create(...e) {
          throw new c.n()
        }
        async update(...e) {
          throw new c.n()
        }
        async delete(...e) {
          throw new c.n()
        }
        async read() {
          const e = new ScanData()
          return (e.scansById = {}), (e.scansByAnchor = {}), Promise.resolve(e)
        }
        async refresh() {
          return this.read()
        }
      }
      const u = new n.Z('scaninfo-module')
      class ScanInfoDataModule extends s.Y {
        constructor() {
          super(...arguments),
            (this.name = 'scaninfo-data'),
            (this.getScanInfo = (e) =>
              this.store.read().then((t) => (t ? t.scansByAnchor[e] : void 0))),
            (this.getScanDownloadURL = (e) =>
              this.store.refresh().then((t) => {
                if (t) {
                  const i = t.scansByAnchor[e]
                  return i ? i.url : void 0
                }
              }))
        }
        async init(e) {
          this.store = this.getStore(e)
        }
        getStore(e) {
          const t = e.storageProvider || r.Xq.JSONSTORE
          return (
            u.info(`Loading Scan Info from ${t}`),
            t === r.Xq.MDS ? new MdsScanInfoStore() : new EmptyScanInfoStore()
          )
        }
      }
    },
    64807: (e, t, i) => {
      'use strict'
      i.d(t, { Z: () => PanoRenderTargetResizedMessage })
      var s = i(91466)
      class PanoRenderTargetResizedMessage extends s.v {
        constructor(e, t, i) {
          super(), (this.size = e), (this.sweepId = t), (this.renderTarget = i)
        }
      }
    },
    77025: (e, t, i) => {
      'use strict'
      i.d(t, {
        D: () => TilingOverrideWindowSizeCommand,
        F: () => TilingSetNavPanoSizeCommand
      })
      var s = i(17386)
      class TilingOverrideWindowSizeCommand extends s.m {
        constructor(e) {
          super(),
            (this.id = 'ALLOW_HIGH_RES'),
            (this.payload = { ignoreWindowSize: e })
        }
      }
      class TilingSetNavPanoSizeCommand extends s.m {
        constructor(e) {
          super(),
            (this.id = 'SET_NAV_PANO_SIZE'),
            (this.payload = { navSize: e })
        }
      }
    },
    52061: (e, t, i) => {
      'use strict'
      i.r(t), i.d(t, { default: () => SweepPanoTiling })
      var s = i(96909),
        n = i(72067),
        r = i(37381),
        o = i(67790),
        a = i(31102)
      class TilingError extends a.y {
        constructor(e) {
          super(e), (this.name = 'PanoTilingError')
        }
      }
      var h = i(88512),
        l = i(2212),
        d = i(9293),
        c = i(12216)
      var u
      !(function (e) {
        ;(e[(e.PreOrder = 0)] = 'PreOrder'),
          (e[(e.PostOrder = 1)] = 'PostOrder')
      })(u || (u = {}))
      class TreeNode {
        constructor(e, t) {
          ;(this.tree = e),
            (this.parent = t),
            (this.children = []),
            (this.id = ++TreeNode._id),
            (this.extra = {}),
            (this.level = -1)
        }
      }
      TreeNode._id = 0
      class TileTree {
        constructor(e, t) {
          ;(this.levels = t),
            (this.tileSize = e),
            (this.root = null),
            (this.allNodes = []),
            m(this)
        }
        getSizeForLevel(e, t) {
          return Math.pow(2, t) * e
        }
        getSubNode(e, t, i) {
          ;(!t || e < this.tileSize) && (t = 0),
            (!i || e < this.tileSize) && (i = 0),
            e < this.tileSize && (e = this.tileSize)
          const s = p(this.tileSize, e)
          return f(this.root, 0, s, t, i)
        }
        deleteAllNodes() {
          this.depthFirst(
            function (e, t, i, s, n) {
              for (let t = 0; t < e.children.length; t++) {
                const i = e.children[t]
                i && ((i.parent = null), (i.tree = null)),
                  (e.children[t] = null)
              }
              e.children.length = 0
            }.bind(this),
            null,
            u.PostOrder
          )
          for (let e = 0; e < this.allNodes.length; e++) {
            const t = this.allNodes[e]
            t && ((t.parent = null), (t.tree = null)), (this.allNodes[e] = null)
          }
          ;(this.allNodes.length = 0), (this.root = null)
        }
        breadthFirst(e) {
          const t = !!(e = e || {}).nullLevelEnd,
            i = e.maxLevel,
            s = e.minLevel,
            n = e.callback,
            r = e.saveVisited,
            o = [],
            a = new TreeNode(this, null)
          let h = 0
          if (this.root)
            for (
              o.push(this.root), o.push(a);
              o.length > 0 && !(i && h > i);

            ) {
              const e = o.shift()
              if (e)
                if (e === a)
                  (!s || h >= s) && (n && t && n(), r && t && r.push(null)),
                    o.length > 0 && o.push(a),
                    h++
                else {
                  if (e.children) for (const t of e.children) t && o.push(t)
                  const t = this.getFaceIndexFromNode(e)
                  ;(!s || h >= s) && (n && n(e, h, t), r && r.push(e))
                }
            }
        }
        getFaceIndexFromNode(e) {
          if (!e) return -1
          let t = 1,
            i = e,
            s = 0,
            n = 0
          for (;;) {
            const e = i.parent
            if (!e) break
            let r = -1
            for (let t = 0; t < e.children.length; t++)
              e.children[t] === i && (r = t)
            ;(s = (r % 2) * t + s),
              (n = Math.floor(r / 2) * t + n),
              (t *= 2),
              (i = e)
          }
          return n * t + s
        }
        depthFirst(e, t, i) {
          g(this.root, 0, 0, 0, e, t, i, this.tileSize)
        }
      }
      const p = function (e, t) {
          let i = 0
          for (t < e && (t = e); !((t /= 2) < e); ) i++
          return i
        },
        g = function (e, t, i, s, n, r, o, a) {
          if (!e) return
          const h = 2 * s + i
          if (
            ((o = o || u.PreOrder) === u.PreOrder &&
              (n && n(e, t, h, i, s), r && r.push(e)),
            !e.children || 0 === e.children.length)
          )
            return
          const l = 2 * s,
            d = 2 * i
          for (let i = 0; i < 2; i++)
            for (let s = 0; s < 2; s++)
              g(e.children[2 * s + i], t + 1, d + i, l + s, n, r, o, a)
          o === u.PostOrder && (n && n(e, t, h, i, s), r && r.push(e))
        },
        m = (e) => {
          e.root = w(e, null, 0)
        },
        w = (e, t, i) => {
          if (i > e.levels) return null
          const s = new TreeNode(e, t)
          ;(s.level = i), e.allNodes.push(s)
          for (let t = 0; t < 4; t++) {
            const n = w(e, s, i + 1)
            n && (s.children[t] = n)
          }
          return s
        },
        f = (e, t, i, s, n) => {
          if (!e) return null
          if (0 === i) return e
          {
            if (!e.children || 0 === e.children.length) return null
            const r = Math.pow(2, i) / 2,
              o = s % r,
              a = n % r,
              h = 2 * Math.floor(n / r) + Math.floor(s / r),
              l = e.children[h]
            return f(l, t + 1, i - 1, o, a)
          }
        }
      var v,
        T = i(14844),
        y = i(14209),
        S = i(52586),
        P = i(44110),
        D = i(34369),
        b = i(17486),
        M = i(27079)
      !(function (e) {
        ;(e[(e.Base = 0)] = 'Base'), (e[(e.Remaining = 1)] = 'Remaining')
      })(v || (v = {}))
      class TileUploadQueue {
        constructor() {
          ;(this.forceQueue = []),
            (this.uploadQueues = {}),
            (this.panoLODDescriptors = {})
        }
        addToForceQueue(e) {
          this.forceQueue.push(e)
        }
        addToPanoQueue(e, t) {
          this.getUploadQueueForPano(e).push(t)
        }
        insertSortedIntoPanoQueue(e, t, i) {
          const s = this.getUploadQueueForPano(t.id)
          M.at.insertSortedPanoTile(s, e, t, i)
        }
        sortQueue(e, t) {
          const i = this.getUploadQueueForPano(e.id)
          M.at.sortTiles(i, e, t)
        }
        getUploadQueueForPano(e) {
          let t = this.uploadQueues[e]
          return t || ((t = []), (this.uploadQueues[e] = t)), t
        }
        hasQueuedTiles() {
          if (this.forceQueue.length > 0) return !0
          for (const e in this.uploadQueues) {
            const t = this.getUploadQueueForSweep(e)
            if (t && t.length > 0) return !0
          }
          return !1
        }
        getUploadQueueForSweep(e) {
          let t = this.uploadQueues[e]
          return t || ((t = []), (this.uploadQueues[e] = t)), t
        }
        getTopUploadQueue(e) {
          let t = null
          for (let i = v.Base; i <= v.Remaining; i++)
            for (const s of e)
              if (((t = this.getUploadQueueForSweep(s.id)), t.length > 0))
                switch (i) {
                  case v.Base:
                    if (0 === t[0].level) return t
                    break
                  case v.Remaining:
                    return t
                }
          return null
        }
        processNextQueueItem(e) {
          const t = e.shift()
          return t ? ((t.uploadQueued = !1), t) : null
        }
        getNextFromUploadQueue(e) {
          if (this.forceQueue.length > 0)
            return this.processNextQueueItem(this.forceQueue)
          const t = this.getTopUploadQueue(e)
          return t && t.length > 0 ? this.processNextQueueItem(t) : null
        }
        peekNextFromUploadQueue(e) {
          if (this.forceQueue.length > 0) return this.forceQueue[0]
          const t = this.getTopUploadQueue(e)
          return t && t.length > 0 ? t[0] : null
        }
        clearAllQueuedUploads() {
          this.clearAllUploadQueues(null, 0)
        }
        clearAllUploadQueues(e, t = 0) {
          if (e)
            this.clearUploadQueue(this.getUploadQueueForSweep(e), t),
              this.clearUploadQueue(this.forceQueue, t, e)
          else {
            for (const e in this.uploadQueues)
              this.clearUploadQueue(this.getUploadQueueForSweep(e), t)
            this.clearUploadQueue(this.forceQueue, t)
          }
        }
        clearUploadQueue(e, t = 0, i) {
          let s = 0
          for (; s < e.length; ) {
            const n = e[s]
            ;(!i || (i && i === n.sweepId)) && n.level >= t
              ? ((n.uploadQueued = !1), e.splice(s, 1))
              : s++
          }
        }
        resetPanoLODDescriptors(e) {
          const t = this.getPanoLODDescriptors(e)
          for (const e in t)
            if (t.hasOwnProperty(e)) {
              const i = t[e]
              ;(i.uploadCount = 0), (i.uploadAttempts = 0)
            }
        }
        getPanoLODDescriptor(e, t) {
          const i = this.getPanoLODDescriptors(e)
          let s = i[t]
          return (
            s || ((s = { uploadCount: 0, uploadAttempts: 0 }), (i[t] = s)), s
          )
        }
        getPanoLODDescriptors(e) {
          let t = this.panoLODDescriptors[e]
          return t || ((t = {}), (this.panoLODDescriptors[e] = t)), t
        }
      }
      var x = i(64807),
        I = i(10757),
        R = i(67502),
        C = i(84842),
        E = i(84303)
      const L = new h.Z('tiles'),
        F = r.Xd.uploadIntervalDelay
      class TiledPanoRenderer extends y.Z {
        constructor(e, t, i, s, n, r, o, a) {
          super(e, n.getSweepList()),
            (this.cwfRenderer = t),
            (this.panoQualityManager = i),
            (this.tileDownloader = s),
            (this.sweepData = n),
            (this.cameraData = r),
            (this.tilingSettings = o),
            (this.broadcast = a),
            (this.persistentStorage = new b.a()),
            (this.activeSweeps = []),
            (this.sweepLoadHistory = []),
            (this.activeRenderTargetDescriptors = {}),
            (this.panoLoadPromises = {}),
            (this.panoLoadResolvers = {}),
            (this.panoLoadTimers = {}),
            (this.tileTrees = {}),
            (this.tileDirectory = {}),
            (this.zoomSweepRenderingDisabled = !1),
            (this.zoomingActive = !1),
            (this.zoomSweepId = null),
            (this.usingTileOverlay = !1),
            (this.overlayTilesLoaded = !1),
            (this.overlayTileBase = null),
            (this.overlayTilesBasic = {}),
            (this.overlayTilesEnhanced = {}),
            (this.tileUploadQueue = new TileUploadQueue()),
            (this.currentState = {
              direction: new l.Vector3(),
              position: new l.Vector3(),
              rotation: new l.Quaternion()
            }),
            (this.renderTargetPool = new d.L(this.rtCompare)),
            this.tileDownloader.setModel(this.sweepListMap),
            this.tileDownloader.setLoadCallbacks(
              this.onTileDownLoaded.bind(this)
            )
        }
        activate(e) {
          this.engine = e
        }
        rtCompare(e, t) {
          return e.object.height === t.size && e.object.width === t.size
        }
        getActivePanos() {
          const e = []
          for (const t of Object.keys(this.activeRenderTargetDescriptors)) {
            this.activeRenderTargetDescriptors[t] && e.push(t)
          }
          return e
        }
        init() {
          super.init(), this.loadOverlayTiles()
        }
        highResRenderTarget(e, t) {
          if (e) {
            if (!t)
              throw new TilingError('Cannot activate zooming without sweepId!')
            ;(this.zoomingActive = !0),
              (this.zoomSweepId = t),
              this.copyTargetToZoom(t)
          } else (this.zoomingActive = !1), (this.zoomSweepId = null)
          if (t) {
            const e = this.getRenderTargetDescriptorForSweep(t)
            if (!e) throw new TilingError('Zooming at a null render target!')
            const i = this.zoomingActive ? this.zoomRenderTarget : e.object,
              s = i.width
            this.broadcast(new x.Z(s, t, i))
          }
        }
        getCurrentPanoResolution() {
          const e = this.zoomingActive
            ? this.panoQualityManager.getZoomPanoSize()
            : this.panoQualityManager.getNavPanoSize()
          return S.Z.getPanoSizeClass(e)
        }
        beforeRender() {
          const e = this.sweepData.currentSweep,
            t = this.sweepData.transition.to
          this.updateState(
            this.cameraData.pose.position,
            this.cameraData.pose.rotation,
            e,
            t
          ),
            this.updateUploadQueueProcessing()
        }
        activateSweep(e) {
          const t = this.sweepListMap.get(e)
          if (!t)
            throw (
              (L.error(e, t),
              new TilingError(
                'Invalid sweepId passed to TiledPanORenderer.activate()'
              ))
            )
          let i = this.panoLoadPromises[e]
          return (
            i ||
              ((this.panoLoadTimers[e] = window.setTimeout(() => {
                this.engine.broadcast(new C.Z_(!0))
              }, r.Xd.loadIndicatorDelay)),
              (i = new Promise((i, s) => {
                ;(this.panoLoadResolvers[e] = i),
                  this.updateSweepState(e),
                  this.activatePano(t),
                  this.queueUploadForAllTiles(e, !0),
                  this.tileDownloader.forceQueueTiles(
                    t,
                    S.Z.getPanoSize(D.SL.BASE),
                    this.currentState.direction,
                    !0
                  )
              })),
              (this.panoLoadPromises[e] = i)),
            super._activateSweep(e),
            i
          )
        }
        useTexture(e) {
          const t = this.getRenderTargetDescriptorForSweep(e)
          if (!t)
            throw (
              (L.error(e),
              Error('Texture for sweep not activated before using'))
            )
          const i = t.object.texture
          return (
            super._useTexture(e),
            this.freeUnusedTextures(),
            this.zoomingActive ? this.zoomRenderTarget.texture : i
          )
        }
        freeTexture(e, t = !1) {
          super.freeTexture(e, t),
            0 === this.textureUsageCounter[e] &&
              ((this.panoLoadPromises[e] = null), this.deactivatePano(e))
        }
        freeAllTextures(e = []) {
          const t = (0, I.ow)(e),
            i = this.getActivePanos()
          for (const e of i) t[e] || this.freeTexture(e, !0)
        }
        enableUltraHighQualityMode(e) {
          this.setupZoomRenderTarget(),
            this.zoomSweepId &&
              this.broadcast(
                new x.Z(
                  this.zoomRenderTarget.width,
                  this.zoomSweepId,
                  this.zoomRenderTarget
                )
              )
        }
        resetRenderStatus(e, t, i, s) {
          let n
          s && (n = p(T.I_, s) + 1)
          const r = (e, s, n, r) => {
            i && (s.extra.tile.zoomUploaded = !1),
              t && (s.extra.tile.uploaded = !1)
          }
          for (let t = 0; t < T.Hq; t++) {
            this.getTileTree(e, t).breadthFirst({
              callback: r.bind(this, t),
              minLevel: n
            })
          }
        }
        copyBaseRenderStatusToZoomed(e) {
          const t = p(T.I_, this.panoQualityManager.getNavPanoSize()),
            i = (e, t, i, s) => {
              ;(t.extra.tile.zoomUploaded = t.extra.tile.uploaded),
                (t.extra.zoomCovered = t.extra.covered)
            }
          for (let s = 0; s < T.Hq; s++) {
            this.getTileTree(e, s).breadthFirst({
              callback: i.bind(this, s),
              maxLevel: t
            })
          }
        }
        renderPanoTiles(e, t, i, s) {
          const n = []
          ;(this.zoomRenderTarget &&
            this.zoomRenderTarget.width ===
              this.panoQualityManager.getZoomPanoSize()) ||
            this.zoomSweepRenderingDisabled ||
            this.setupZoomRenderTarget(),
            (t = t || this.currentState.direction || c.f.FORWARD)
          const r = this.getRenderTargetDescriptorForSweep(e)
          if (!this.isRenderTargetDescriptorValid(r))
            throw new TilingError(
              'PanoRenderer.renderPanoTiles() -> Cannot render to a pano that is not activated.'
            )
          for (let t = 0; t < T.Hq; t++) {
            const r = this.getTileTree(e, t)
            ;(n.length = 0), r.breadthFirst({ saveVisited: n })
            for (let e = 0; e < n.length; e++) {
              const t = n[e]
              this.queueUploadForTile(t.extra.tile, !1, s || (0 === e && i))
            }
          }
        }
        clearAllQueuedUploads() {
          this.tileUploadQueue.clearAllUploadQueues(null, 0)
        }
        clearAllQueuedUploadsForPano(e) {
          this.tileUploadQueue.clearAllUploadQueues(e, 0)
        }
        updateState(e, t, i, s) {
          const n = s || i || this.currentState.sweepId,
            r = n ? this.sweepListMap.get(n) : null
          this.updatePositionState(e),
            this.updateRotationState(t),
            n && this.updateSweepState(n),
            r &&
              this.tileDownloader.tilePrioritizer &&
              this.tileDownloader.tilePrioritizer.updateCriteria(
                r,
                e,
                this.currentState.direction,
                this.currentState.rotation
              )
        }
        updatePositionState(e) {
          this.currentState.position.copy(e)
        }
        updateRotationState(e) {
          if (
            (this.currentState.rotation.copy(e),
            this.currentState.direction.copy(c.f.FORWARD).applyQuaternion(e),
            this.tileUploadQueue.hasQueuedTiles())
          )
            for (const e of this.activeSweeps)
              this.tileUploadQueue.sortQueue(e, this.currentState.direction)
        }
        updateSweepState(e) {
          this.currentState.sweepId = e
        }
        activatePano(e) {
          this.tileUploadQueue.clearAllQueuedUploads()
          const t = this.panoQualityManager.getMaxPossiblePanoSize()
          for (let i = 0; i < T.Hq; i++) this.initTileTree(e.id, i, t)
          this.linkAllTilesAndNodes(e)
          let i = this.getRenderTargetDescriptorForSweep(e.id)
          if (!i) {
            const t = this.panoQualityManager.getNavPanoSize()
            if (((i = this.renderTargetPool.get({ size: t })), !i)) {
              const e = this.cwfRenderer.initRenderTargetCube(t)
              ;(i = this.renderTargetPool.add(e)),
                (i.extra = {}),
                (i.extra.size = e.width)
            }
            ;(i.extra.sweep = e),
              (i.extra.sweepindex = e.index),
              this.setRenderTargetDescriptorForSweep(e.id, i),
              this.tileUploadQueue.resetPanoLODDescriptors(e.id),
              this.resetUploadState(e.id, !0, !0)
          }
          return this.updateActiveSweeps(e), i.object
        }
        deactivatePano(e) {
          const t = this.getRenderTargetDescriptorForSweep(e)
          t &&
            this.isRenderTargetDescriptorValid(t) &&
            (this.renderTargetPool.free(t.object),
            this.setRenderTargetDescriptorForSweep(e, null),
            this.updateActiveSweeps(),
            this.tileUploadQueue.clearAllUploadQueues(e),
            this.tileUploadQueue.resetPanoLODDescriptors(e),
            this.clearCachedTileData())
        }
        clearCachedTileData() {
          for (let e = this.sweepLoadHistory.length - 1; e >= 0; e--) {
            let t = !1
            const i = this.sweepLoadHistory[e]
            if (i) {
              for (const e of this.activeSweeps)
                if (i === e.id) {
                  t = !0
                  break
                }
              !t &&
                this.checkTileTreeInitialized(i) &&
                (this.clearTileState(i, !0, !0),
                this.deleteTileTrees(i),
                this.deleteTileDirectoryEntries(i),
                this.tileDownloader.deleteAllTileDownloadDescriptors(i),
                (this.sweepLoadHistory[e] = null))
            }
          }
          this.updateSweepLoadHistory()
        }
        updateActiveSweeps(e) {
          const t = this.persistentStorage.getArray(
            'updateActiveSweeps:tempSweeps'
          )
          t.length = 0
          for (const i of this.activeSweeps) {
            const s = this.getRenderTargetDescriptorForSweep(i.id)
            ;(e && i.id === e.id) ||
              !this.isRenderTargetDescriptorValid(s) ||
              t.push(i)
          }
          e && t.unshift(e),
            (this.activeSweeps.length = 0),
            this.activeSweeps.push(...t)
        }
        queueUploadForAllTiles(e, t = !0) {
          ;(this.zoomRenderTarget &&
            this.zoomRenderTarget.width ===
              this.panoQualityManager.getZoomPanoSize()) ||
            this.zoomSweepRenderingDisabled ||
            this.setupZoomRenderTarget()
          const i = this.getRenderTargetDescriptorForSweep(e)
          if (!this.isRenderTargetDescriptorValid(i))
            throw new TilingError(
              'queueUploadForAllTiles() -> Cannot render to a pano that is not activated.'
            )
          const s = this.persistentStorage.getArray(
            'queueUploadForAllTiles:nodeList'
          )
          for (let i = 0; i < T.Hq; i++) {
            const n = this.getTileTree(e, i)
            ;(s.length = 0), n.breadthFirst({ saveVisited: s })
            for (const e of s)
              this.queueUploadForTile(e.extra.tile, !1, 0 === e.level && t)
          }
        }
        onTileDownLoaded(e) {
          if (!e.sweep) return
          const t = p(T.I_, e.panoSize),
            i = this.getTileDirectoryEntry(
              e.sweep.id,
              e.face,
              t,
              e.faceTileIndex
            )
          this.updateUploadDescriptorFromDownloadDescriptor(i, e),
            this.updateSweepLoadHistory(i.sweepId)
          const s = this.getRenderTargetDescriptorForSweep(i.sweepId)
          if (this.isRenderTargetDescriptorValid(s)) {
            const e = this.getTileTree(i.sweepId, i.face).getSubNode(
              i.panoSize,
              i.tileX,
              i.tileY
            )
            e && (this.linkTileAndNode(i, e), this.queueUploadForTile(i, !0))
          }
        }
        updateUploadDescriptorFromDownloadDescriptor(e, t) {
          ;(e.downloaded = !0),
            (e.image = t.image),
            (e.panoSize = t.panoSize),
            (e.tileX = t.tileX),
            (e.tileY = t.tileY),
            (e.totalTiles = t.totalTiles),
            (e.tileIndex = t.tileIndex),
            (e.faceTileIndex = t.faceTileIndex),
            (e.face = t.face),
            (e.cubeFace = P.m(t.face)),
            t.sweep && (e.sweepId = t.sweep.id),
            (e.tileSize = t.tileSize),
            e.direction.copy(t.direction),
            (e.node = null),
            (e.level = p(T.I_, e.panoSize))
        }
        updateSweepLoadHistory(e) {
          const t = this.persistentStorage.getArray(
            'updateSweepLoadHistory:tempHistory'
          )
          t.length = 0
          for (const i of this.sweepLoadHistory)
            i && (!e || (e && e !== i)) && t.push(i)
          ;(this.sweepLoadHistory.length = 0),
            e && this.sweepLoadHistory.push(e),
            this.sweepLoadHistory.push(...t)
        }
        onPanoRendered(e, t, i, s) {
          clearTimeout(this.panoLoadTimers[e]),
            this.engine.broadcast(new C.Z_(!1))
          const n = this.panoLoadResolvers[e],
            r = this.activeRenderTargetDescriptors[e]
          r && r.object && n(r.object.texture)
        }
        getRenderTargetDescriptorForSweep(e) {
          return this.activeRenderTargetDescriptors[e]
        }
        setRenderTargetDescriptorForSweep(e, t) {
          this.activeRenderTargetDescriptors[e] = t
        }
        isRenderTargetDescriptorValid(e) {
          return !!e && !!e.object
        }
        isSweepZoomed(e) {
          return this.zoomingActive && this.zoomSweepId === e
        }
        initTileTree(e, t, i) {
          let s = this.tileTrees[e]
          s || ((s = []), (this.tileTrees[e] = s))
          let n = s[t]
          if (!n) {
            const e = p(T.I_, i)
            ;(n = new TileTree(T.I_, e)), (s[t] = n)
          }
        }
        getTileTrees(e) {
          const t = this.tileTrees[e]
          if (!t)
            throw new TilingError(
              'TiledPanoRenderer.getTileTrees() -> Tree array not yet initialized!'
            )
          return t
        }
        checkTileTreeInitialized(e) {
          return !!this.tileTrees[e]
        }
        getTileTree(e, t) {
          const i = this.getTileTrees(e)[t]
          if (!i)
            throw new TilingError(
              'TiledPanoRenderer.getTileTree() -> Tree not yet initialized!'
            )
          return i
        }
        deleteTileTrees(e) {
          const t = this.getTileTrees(e)
          for (let e = 0; e < T.Hq; e++) {
            const i = t[e]
            i && i.deleteAllNodes()
          }
          ;(this.tileTrees[e] = null), delete this.tileTrees[e]
        }
        clearTileState(e, t = !1, i = !1) {
          const s = (e, s, n, r) => {
            i && (s.extra.tile.image = null),
              t &&
                ((s.extra.tile.uploaded = !1),
                (s.extra.tile.downloaded = !1),
                (s.extra.tile.zoomUploaded = !1),
                (s.extra.tile.uploadAttempted = !1))
          }
          for (let t = 0; t < T.Hq; t++) {
            const i = this.getTileTree(e, t)
            i &&
              i.breadthFirst({
                callback: s.bind(this, t),
                maxLevel: p(T.I_, this.panoQualityManager.getZoomPanoSize())
              })
          }
        }
        resetUploadState(e, t, i) {
          const s = (e, s, n, r) => {
            ;(s.extra.tile.zoomUploaded = !i && s.extra.tile.zoomUploaded),
              (s.extra.tile.uploaded = !t && s.extra.tile.uploaded)
          }
          for (let t = 0; t < T.Hq; t++) {
            this.getTileTree(e, t).breadthFirst({
              callback: s.bind(this, t),
              minLevel: 0
            })
          }
        }
        anyUploaded(e) {
          if (!e) return !1
          if (e.extra.tile && this.isTileUploaded(e.extra.tile)) return !0
          if (e.children)
            for (const t of e.children) if (this.anyUploaded(t)) return !0
          return !1
        }
        linkTileAndNode(e, t) {
          ;(t.extra.tile = e), (e.node = t)
        }
        linkAllTilesAndNodes(e) {
          const t = (t, i, s, n, r) => {
            const o = this.getTileDirectoryEntry(e.id, i, n, r)
            this.linkTileAndNode(o, s)
          }
          for (let i = 0; i < T.Hq; i++) {
            const s = this.getTileTree(e.id, i)
            s.breadthFirst({ callback: t.bind(this, s, i) })
          }
        }
        getTileDirectoryEntry(e, t, i, s) {
          let n = this.tileDirectory[e]
          n || ((n = {}), (this.tileDirectory[e] = n))
          const r = 16384 * t + 1024 * i + s
          let o = n[r]
          return (
            o ||
              ((o = {
                downloaded: !1,
                uploaded: !1,
                uploadAttempted: !1,
                zoomUploaded: !1,
                uploadQueued: !1,
                image: null,
                panoSize: -1,
                tileX: -1,
                tileY: -1,
                totalTiles: -1,
                tileIndex: s,
                faceTileIndex: -1,
                face: t,
                cubeFace: -1,
                sweepId: e,
                tileSize: -1,
                direction: new l.Vector3(),
                node: null,
                level: i
              }),
              (n[r] = o)),
            (o._tileKey = r),
            o
          )
        }
        deleteTileDirectoryEntries(e) {
          ;(this.tileDirectory[e] = null), delete this.tileDirectory[e]
        }
        isTileUploaded(e) {
          return this.isSweepZoomed(e.sweepId) ? e.zoomUploaded : e.uploaded
        }
        setUploaded(e, t) {
          this.isSweepZoomed(e.sweepId)
            ? (e.zoomUploaded = t)
            : (e.uploaded = t)
        }
        queueUploadForTile(e, t, i) {
          const s =
              !e.downloaded ||
              (e.uploadQueued && !i) ||
              this.isTileUploaded(e) ||
              (e.panoSize > this.panoQualityManager.getNavPanoSize() &&
                !this.zoomingActive),
            n = this.getRenderTargetDescriptorForSweep(e.sweepId)
          !s &&
            n &&
            this.isRenderTargetDescriptorValid(n) &&
            (i
              ? this.uploadTile(e)
              : (0 === p(T.I_, e.panoSize)
                  ? this.tileUploadQueue.addToForceQueue(e)
                  : t && this.currentState.direction
                  ? this.tileUploadQueue.insertSortedIntoPanoQueue(
                      e,
                      n.extra.sweep,
                      this.currentState.direction
                    )
                  : this.tileUploadQueue.addToPanoQueue(e.sweepId, e),
                (e.uploadQueued = !0)))
        }
        uploadTile(e) {
          const t = this.persistentStorage.get(
              'uploadTile:tempTileTexture',
              () => ({})
            ),
            i = this.tileUploadQueue.getPanoLODDescriptor(
              e.sweepId,
              e.panoSize
            ),
            s = this.getRenderTargetDescriptorForSweep(e.sweepId)
          if (!s || !e.image || !this.isRenderTargetDescriptorValid(s)) return
          let n = s.object,
            o = s.extra.size
          if (
            (this.isSweepZoomed(e.sweepId) &&
              ((n = this.zoomRenderTarget),
              (o = this.panoQualityManager.getZoomPanoSize())),
            this.isTileUploaded(e) || this.anyUploaded(e.node))
          )
            this.setUploaded(e, !1)
          else {
            const s = e.tileX * e.tileSize,
              a = e.tileY * e.tileSize,
              h = (e.tileSize / e.panoSize) * o,
              d = (s / e.panoSize) * o,
              c = (a / e.panoSize) * o
            let u = t[e.tileSize]
            if (
              (t[e.tileSize] ||
                ((u = new l.Texture()),
                (u.generateMipmaps = !1),
                (u.minFilter = l.LinearFilter),
                (u.flipY = !1),
                this.cwfRenderer.initSizedTexture2D(e.tileSize, u),
                (t[e.tileSize] = u)),
              this.cwfRenderer.uploadTexture2D(e.image, u, 0, 0),
              this.cwfRenderer.renderToCubeMap(
                u,
                n,
                e.tileSize,
                e.tileSize,
                0,
                0,
                e.tileSize,
                e.tileSize,
                d,
                c,
                h,
                h,
                e.cubeFace
              ),
              r.Xd.overlayStyle > 0)
            ) {
              const t =
                1 === r.Xd.overlayStyle
                  ? this.overlayTilesBasic
                  : this.overlayTilesEnhanced
              this.cwfRenderer.renderToCubeMap(
                t[e.panoSize],
                n,
                e.tileSize,
                e.tileSize,
                0,
                0,
                e.tileSize,
                e.tileSize,
                d,
                c,
                h,
                h,
                e.cubeFace,
                l.NormalBlending,
                !0,
                0.5
              )
            }
            i.uploadCount++, this.setUploaded(e, !0)
          }
          e.uploadAttempted || i.uploadAttempts++,
            (e.uploadAttempted = !0),
            i.uploadAttempts === e.totalTiles &&
              this.onPanoRendered(e.sweepId, e.panoSize, e.totalTiles)
        }
        updateUploadQueueProcessing() {
          if (
            !this.currentUploadPromise &&
            (this.overlayTilesLoaded || !this.usingTileOverlay)
          ) {
            const e = new R._(
              'pano/tiling/upload',
              () =>
                this.engine
                  .after(E.A.End)
                  .then(() =>
                    this.processUploadQueue(
                      this.tilingSettings.highResUploadsPerFrame,
                      this.tilingSettings.uploadsPerFrame
                    )
                  ),
              F
            )
            this.currentUploadPromise = this.engine.commandBinder
              .issueCommand(e)
              .then(async (e) => {
                await e.promise, (this.currentUploadPromise = null)
              })
          }
        }
        processUploadQueue(e = 1, t) {
          let i = 0,
            s = 0,
            n = null
          for (
            ;
            (n = this.tileUploadQueue.getNextFromUploadQueue(
              this.activeSweeps
            ));

          ) {
            const r = this.getRenderTargetDescriptorForSweep(n.sweepId)
            if (
              !(
                (n.panoSize > this.panoQualityManager.getNavPanoSize() &&
                  !this.zoomingActive) ||
                !this.isRenderTargetDescriptorValid(r)
              ) &&
              (this.uploadTile(n),
              (i += 0 !== n.level ? 1 : 0),
              (s += 0 === n.level ? 1 : 0),
              s >= t || i >= e)
            )
              break
          }
        }
        loadOverlayTiles() {
          if (0 !== r.Xd.overlayStyle) {
            let e = 0
            const t = [],
              s = (i, s, n) => {
                let r = new l.Texture()
                ;(r.generateMipmaps = !1),
                  (r.minFilter = l.LinearFilter),
                  (r.flipY = !1),
                  s
                    ? (r = i[s] = this.cwfRenderer.initSizedTexture2D(T.I_, r))
                    : ((this.overlayTileBase =
                        this.cwfRenderer.initSizedTexture2D(T.I_, r)),
                      (r = this.overlayTileBase)),
                  this.cwfRenderer.uploadTexture2D(n, r, 0, 0),
                  e++,
                  e >= t.length && (this.overlayTilesLoaded = !0)
              }
            switch (r.Xd.overlayStyle) {
              case 1:
                t.push([i(67929), this.overlayTilesBasic, 256]),
                  t.push([i(67929), this.overlayTilesBasic, 512]),
                  t.push([i(27273), this.overlayTilesBasic, 1024]),
                  t.push([i(15278), this.overlayTilesBasic, 2048]),
                  t.push([i(92787), this.overlayTilesBasic, 4096])
                break
              case 2:
                t.push([i(33967), this.overlayTilesEnhanced, 256]),
                  t.push([i(33967), this.overlayTilesEnhanced, 512]),
                  t.push([i(53896), this.overlayTilesEnhanced, 1024]),
                  t.push([i(38343), this.overlayTilesEnhanced, 2048]),
                  t.push([i(73965), this.overlayTilesEnhanced, 4096])
            }
            t.forEach((e) => {
              const t = document.createElement('img')
              ;(t.crossOrigin = 'anonymous'),
                (t.src = e[0]),
                (t.onload = () => {
                  s.call(this, e[1], e[2], t)
                })
            }),
              (this.usingTileOverlay = !0)
          } else this.usingTileOverlay = !1
        }
        copyTargetToZoom(e) {
          if (!this.zoomingActive) return
          const t = this.getRenderTargetDescriptorForSweep(e)
          if (!t)
            throw new TilingError(
              'Error in copying a null render target to a zoomed target'
            )
          const i = t.object
          this.cwfRenderer.copyCubemap(i.texture, this.zoomRenderTarget),
            this.copyBaseRenderStatusToZoomed(e)
        }
        setupZoomRenderTarget() {
          if (
            this.panoQualityManager.getZoomPanoSize() >=
            this.panoQualityManager.getNavPanoSize()
          ) {
            if (
              this.zoomRenderTarget &&
              this.zoomRenderTarget.width ===
                this.panoQualityManager.getZoomPanoSize()
            )
              return
            const e = this.zoomRenderTarget
            ;(this.zoomRenderTarget = this.cwfRenderer.initRenderTargetCube(
              this.panoQualityManager.getZoomPanoSize()
            )),
              e &&
                (this.cwfRenderer.copyCubemap(e.texture, this.zoomRenderTarget),
                e.texture.dispose(),
                (e.texture.version = 0),
                this.cwfRenderer.deallocateCubeTexture(e.texture),
                (e.texture = null)),
              (this.zoomSweepRenderingDisabled = !1)
          } else this.zoomSweepRenderingDisabled = !0
        }
      }
      var k = i(91715),
        A = i(32867),
        N = i(20331),
        O = i(50401)
      const G = new h.Z('tile-downloader')
      class TileDownloader {
        constructor(e, t, i, s) {
          ;(this.urls = e),
            (this.panoQualityManager = t),
            (this.tilePrioritizer = i),
            (this.settings = s),
            (this.persistentStorage = new b.a()),
            (this.downloadDescriptors = {}),
            (this.priorityQueue = []),
            (this.forceQueue = []),
            (this.activeDownloads = []),
            (this.lastPrioritizedTime = Date.now()),
            (this.processPriorityQueue = !0)
        }
        init() {}
        render() {
          this.update()
        }
        update() {
          this.processQueue(this.forceQueue, !1),
            this.processPriorityQueue &&
              (!this.processQueuePromise &&
                this.sweepListMap &&
                this.activeDownloads.length <
                  this.settings.concurrentDownloads &&
                Date.now() - this.lastPrioritizedTime > 200 &&
                (this.processQueuePromise = this.engine.commandBinder
                  .issueCommand(
                    new R._(
                      'pano/tiling/queue-download',
                      () => {
                        this.queuePrioritizedTiles(this.sweepListMap),
                          (this.lastPrioritizedTime = Date.now())
                      },
                      100
                    )
                  )
                  .then(async (e) => {
                    await e.promise, (this.processQueuePromise = null)
                  })),
              this.processQueue(this.priorityQueue, !1))
        }
        dispose() {}
        activate(e) {
          this.engine = e
        }
        deactivate(e) {}
        setModel(e) {
          this.setSweeps(e)
        }
        setRestrictedSweeps(e) {
          if (this.sweepListMap && this.tilePrioritizer) {
            const t = []
            for (const i of e) t.push(this.sweepListMap.get(i))
            this.tilePrioritizer.setUpcomingSweeps(t),
              this.clearFromAllQueuesBySweep(e)
          }
        }
        clearRestrictedSweeps() {
          this.tilePrioritizer && this.tilePrioritizer.clearUpcomingSweeps()
        }
        setLoadCallbacks(e, t) {
          ;(this.onTileDownloaded = e), (this.onPanoDownloaded = t)
        }
        setSweeps(e) {
          this.sweepListMap = e
        }
        getNonDownloadedTiles(e, t, i) {
          i.length = 0
          const s = this.getTileDownloadDescriptors(e, t)
          for (const e of s)
            !e ||
              (e.status !== A.Z.None && e.status !== A.Z.Queued) ||
              i.push(e)
        }
        forceQueueTiles(e, t, i, s, n, r) {
          const o = this.persistentStorage.getArray(
              'forceQueueTiles:remaining'
            ),
            a = this.persistentStorage.getArray('forceQueueTiles:matching'),
            h = this.persistentStorage.getArray('forceQueueTiles:toDownload')
          if (
            (this.getNonDownloadedTiles(e, t, o), (h.length = 0), o.length > 0)
          ) {
            M.at.sortTiles(o, e, i), (a.length = 0), T.oU(e, t, i, a, !0)
            for (const e of o)
              for (const t of a)
                e.face === t.face &&
                  e.faceTileIndex === t.faceTileIndex &&
                  h.push(e)
            this.forceQueue.push.apply(this.forceQueue, h),
              this.setStatusForAllDescriptors(this.forceQueue, A.Z.ForceQueued),
              this.clearFromQueue(this.priorityQueue, A.Z.ForceQueued, !1),
              s && this.processQueue(this.forceQueue, !0)
          }
        }
        clearForceQueue() {
          this.clearQueue(this.forceQueue)
        }
        queuePrioritizedTiles(e) {
          this.tilePrioritizer &&
            (this.clearQueue(this.priorityQueue),
            this.tilePrioritizer.filterAndPrioritize(
              this.priorityQueue,
              e,
              this
            ),
            this.invalidateDuplicateEntries(this.priorityQueue),
            this.clearFromQueue(this.priorityQueue, A.Z.None, !0),
            this.setStatusForAllDescriptors(this.priorityQueue, A.Z.Queued),
            (this.lastPrioritizedTime = Date.now()))
        }
        clearQueue(e) {
          this.setStatusForAllDescriptors(e, A.Z.None), (e.length = 0)
        }
        clearFromQueue(e, t, i) {
          for (let s = 0; s < e.length; s++) {
            const n = e[s]
            n &&
              ((t === n.status && !i) || (t !== n.status && i)) &&
              (e[s] = null)
          }
        }
        clearFromAllQueuesBySweep(e) {
          this.clearFromQueueBySweep(this.forceQueue, e),
            this.clearFromQueueBySweep(this.priorityQueue, e)
        }
        clearFromQueueBySweep(e, t) {
          const i = (0, I.ow)(t)
          for (let t = 0; t < e.length; t++) {
            const s = e[t]
            s && s.sweep && (i[s.sweep.id] || (e[t] = null))
          }
        }
        setStatusForAllDescriptors(e, t) {
          for (const i of e) i && (i.status = t)
        }
        invalidateDuplicateEntries(e) {
          for (const t of e) t && (t.queuedCount = 0)
          for (let t = 0; t < e.length; t++) {
            const i = e[t]
            i && (i.queuedCount++, i.queuedCount > 1 && (e[t] = null))
          }
        }
        getTileDownloadDescriptors(e, t) {
          const i = this.getAllTileDownloadDescriptors(e.id)
          let s = i[t]
          return (
            s ||
              ((s = this.buildDownloadDescriptorArray(t)),
              (i[t] = s),
              this.initTileDownloadDescriptors(s, e, t)),
            s
          )
        }
        getAllTileDownloadDescriptors(e) {
          let t = this.downloadDescriptors[e]
          return t || ((t = {}), (this.downloadDescriptors[e] = t)), t
        }
        deleteAllTileDownloadDescriptors(e) {
          ;(this.downloadDescriptors[e] = null),
            delete this.downloadDescriptors[e]
        }
        processQueue(e, t) {
          if (
            (this.cleanupActiveDownloads(),
            this.activeDownloads.length < this.settings.concurrentDownloads ||
              t)
          ) {
            const i = t
              ? e.length
              : this.settings.concurrentDownloads - this.activeDownloads.length
            let s = 0
            for (let t = 0; s < i && e.length > 0; t++) {
              const t = e.shift()
              t && (this.startDownload(t), s++)
            }
          }
        }
        async startDownload(e) {
          if (!this.urls)
            throw new Error("Can't call startDownload without signed urls")
          if (e.sweep) {
            const t =
              e.status === A.Z.ForceQueued
                ? N.RequestPriority.HIGHEST
                : N.RequestPriority.MEDIUM
            e.status = A.Z.Downloading
            this.checkRestrictedSweep(e.sweep.id) ||
              G.warn('Downloading a tile that is not in restricted list'),
              this.activeDownloads.push(e)
            const i = await this.panoQualityManager.getTileUrl(
              e.sweep,
              e.panoSize,
              e.tileSize,
              e.tileIndex
            )
            this.urls
              .getImageBitmap(i, e.tileSize, e.tileSize, {
                maxRetries: 3,
                priority: t
              })
              .then(
                this.downloadComplete.bind(this, e),
                this.downloadFailed.bind(this, e)
              )
          }
        }
        checkRestrictedSweep(e) {
          if (this.tilePrioritizer) {
            const t = this.tilePrioritizer.priorityCriteria.upcomingSweeps
            if (t) {
              let i = !1
              for (const s of t) s && s.id === e && (i = !0)
              return i
            }
            return !0
          }
          return !0
        }
        downloadFailed(e, t) {
          e.status = A.Z.DownloadFailed
        }
        downloadComplete(e, t) {
          if (
            e.sweep &&
            ((e.status = A.Z.Downloaded),
            (e.image = t),
            this.onTileDownloaded && this.onTileDownloaded(e),
            this.engine.broadcast(new O.o()),
            this.isPanoDownloaded(e.sweep, e.panoSize))
          ) {
            const t = {
              sweep: e.sweep,
              tileSize: e.tileSize,
              panoSize: e.panoSize
            }
            this.onPanoDownloaded && this.onPanoDownloaded(t)
          }
        }
        cleanupActiveDownloads() {
          const e = this.persistentStorage.getArray(
            'cleanupActiveDownloads:temp'
          )
          e.length = 0
          for (const t of this.activeDownloads)
            t.status !== A.Z.Downloaded &&
              t.status !== A.Z.DownloadFailed &&
              e.push(t)
          ;(this.activeDownloads.length = 0),
            this.activeDownloads.push.apply(this.activeDownloads, e)
        }
        isPanoDownloaded(e, t) {
          const i = this.getTileDownloadDescriptors(e, t)
          if (!i || i.length <= 0) return !1
          for (const e of i) if (e && e.status !== A.Z.Downloaded) return !1
          return !0
        }
        buildDownloadDescriptorArray(e) {
          const t = T.Tu(e),
            i = []
          for (let e = 0; e < t; e++) {
            const e = this.buildDownloadDescriptor()
            i.push(e)
          }
          return i
        }
        buildDownloadDescriptor() {
          return {
            sweep: null,
            panoSize: -1,
            tileSize: -1,
            tileIndex: -1,
            totalTiles: -1,
            faceTileIndex: -1,
            status: A.Z.None,
            url: null,
            image: null,
            direction: new l.Vector3(),
            face: -1,
            cubeFace: -1,
            tileX: -1,
            tileY: -1,
            queuedCount: -1
          }
        }
        initTileDownloadDescriptors(e, t, i) {
          for (let s = 0; s < e.length; s++) {
            const n = e[s]
            n && this.initTileDownloadDescriptor(n, t, i, s)
          }
        }
        initTileDownloadDescriptor(e, t, i, s) {
          const n = i >= T.I_ ? T.I_ : i
          ;(e.face = T.R5(i, s)),
            (e.cubeFace = P.m(e.face)),
            (e.sweep = t),
            (e.panoSize = i),
            (e.tileSize = n),
            (e.tileIndex = s),
            (e.totalTiles = T.Tu(i)),
            (e.status = A.Z.None),
            (e.image = null),
            T.Tp(e.panoSize, e.tileIndex, e),
            T.P6(
              e.panoSize,
              e.tileSize,
              e.cubeFace,
              e.tileX,
              e.tileY,
              k.Z.Center,
              0,
              e.direction
            )
        }
      }
      var z = i(909),
        V = i(48280),
        U = i(44218),
        B = i(75892),
        Q = i(69569),
        _ = i(41862),
        H = i(59088),
        j = i(64185),
        q = i(33874),
        Z = i(77025),
        X = i(44019),
        W = i(98828),
        Y = i(84394),
        $ = i(7170),
        K = i(24285),
        J = i(35015)
      const ee = new h.Z('sweep-pano-tiling')
      class SweepPanoTiling extends Q.Z {
        constructor() {
          super(...arguments),
            (this.name = 'sweep-pano-tiling'),
            (this.preloadQuality = null),
            (this.preloadResolution = null),
            (this.handlePlayerResize = (e, t) => {
              const i = this.currentResolution()
              this.panoRenderer.panoQualityManager.setWindowSize(
                e.width,
                e.height
              )
              i !== this.currentResolution() && t && this.resetPano(t)
            })
        }
        async init(e, t) {
          const i = await t.getModule(U.default),
            a = await t.getModuleBySymbol(s.y.WEBGL_RENDERER),
            h = await t.market.waitForData(B.Z)
          this.cameraData = await t.market.waitForData(H.M_)
          const l = await t.market.waitForData(X.P)
          this.settingsData = await t.market.waitForData(q.e)
          const d = a.cwfRenderer,
            c = a.maxCubemapSize,
            u = i.getSignedUrls()
          ;(this.settings = new r.k4()),
            (this.qualityManager = new S.Z(
              u,
              c,
              e.navPanoSize,
              e.zoomPanoSize
            )),
            (this.tilePrioritizer = new M.at(
              this.qualityManager,
              this.settings,
              h,
              l
            )),
            (this.tileDownloader = new TileDownloader(
              u,
              this.qualityManager,
              this.tilePrioritizer,
              this.settings
            )),
            (this.panoRenderer = new TiledPanoRenderer(
              u,
              d,
              this.qualityManager,
              this.tileDownloader,
              h,
              this.cameraData,
              this.settings,
              (e) => t.broadcast(e)
            )),
            t.addComponent(this, this.tileDownloader),
            t.addComponent(this, this.panoRenderer),
            this.bindings.push(
              t.subscribe(K.Z, (e) => {
                this.setTilingFOV()
              }),
              t.subscribe(o.a, (e) => {
                this.handlePlayerResize(e, h.currentSweep), this.setTilingFOV()
              }),
              t.subscribe(z.Z, (e) => {
                this.tileDownloader.setRestrictedSweeps(e.sweepIds)
              }),
              t.subscribe(V.Z, (e) => {
                this.tileDownloader.clearRestrictedSweeps()
              }),
              t.subscribe(Y.Z, (e) => {
                const t = h.getSweep(e.sweepId)
                this.setHoverPreloadSweep(e.hovered ? t : void 0)
              }),
              t.subscribe(J.a, (e) => {
                this.tilePrioritizer.priorityCriteria.viewMode = e.toMode
              }),
              h.onPropertyChanged('transitionActive', () => {
                if (h.transition.to) {
                  const e = h.getSweep(h.transition.to)
                  this.handlePreloadQualityChange(e)
                }
              }),
              this.settingsData.onPropertyChanged(r.YS, () => {
                ;(this.preloadQuality = this.settingsData.tryGetProperty(
                  r.YS,
                  null
                )),
                  this.qualityManager.overrideWindowMaximums(
                    null !== this.preloadQuality
                  ),
                  h.currentSweepObject &&
                    this.handlePreloadQualityChange(h.currentSweepObject)
              }),
              t.commandBinder.addBinding(Z.D, async (e) => {
                this.qualityManager.overrideWindowMaximums(e.ignoreWindowSize)
              }),
              t.commandBinder.addBinding(Z.F, async (e) => {
                this.qualityManager.updateNavPanoSize(e.navSize)
              })
            ),
            this.setTilingFOV(),
            (0, W.h)('debug', '') && n.Z.load(n.Z.menus.PanoPreload, t)
        }
        setTilingFOV() {
          const e = this.cameraData.fovX(),
            t = this.cameraData.fovY(),
            i = Math.max(e, t) * $.MN
          this.tilePrioritizer.setDownloadFOV(i)
        }
        getRenderer() {
          return this.panoRenderer
        }
        setHoverPreloadSweep(e) {
          this.tilePrioritizer && this.tilePrioritizer.setHoveredSweep(e)
        }
        async handlePreloadQualityChange(e) {
          if (null !== this.preloadQuality) {
            const t = await this.availableResolution(e, this.preloadQuality)
            this.preloadResolution = S.Z.getPanoSize(t)
          } else this.preloadResolution = null
          this.enableHighRes(!1)
        }
        enableHighRes(e = !0, t) {
          const i =
            null !== this.preloadResolution
              ? this.preloadResolution
              : e
              ? this.qualityManager.getZoomPanoSize()
              : this.qualityManager.getNavPanoSize()
          this.tilePrioritizer.maxResolution !== i &&
            ee.debug(`Setting max resolution: ${i}`),
            (this.tilePrioritizer.maxResolution = i),
            this.panoRenderer.highResRenderTarget(e, t)
        }
        async enableZooming(e, t) {
          if (e) {
            const e = S.Z.getPanoSizeClass(
              this.qualityManager.getZoomPanoSize()
            )
            return (await this.requestResolution(t, e)) >= e
          }
          return (
            this.enableHighRes(!1, t.id),
            this.resetPano(t.id),
            Promise.resolve(!1)
          )
        }
        async requestResolution(e, t, i = _.v.CurrentView, s = !1) {
          ;(this.settings.highResUploadsPerFrame = s
            ? r.Xd.maxHighResUploadsPerFrame
            : r.Xd.highResUploadsPerFrame),
            (this.settings.concurrentDownloads = s
              ? r.Xd.maxConcurrentDownloads
              : r.Xd.concurrentDownloads),
            (this.settings.downloadFullPano = i === _.v.FullPanorama)
          const n = await this.availableResolution(e, t)
          return (
            n > D.SL.HIGH &&
              (this.qualityManager.overrideWindowMaximums(!0),
              this.panoRenderer.enableUltraHighQualityMode(e.id)),
            (this.currentResolution() < n ||
              S.Z.getPanoSize(n) > this.qualityManager.getNavPanoSize()) &&
              (this.enableHighRes(!0, e.id), this.resetPano(e.id)),
            n
          )
        }
        waitForQueue(e, t, i = 1e3) {
          const s = new j.Q(),
            n = () => {
              a.cancel(), s.notify(1), s.resolve()
            }
          let r = this.tilePrioritizer.getQualityQueueSize(e, t),
            o = window.setTimeout(() => {
              ee.debug(
                `Download queue ${e} timed out from inactivity after ${i}ms`
              ),
                n()
            }, i)
          const a = this.tilePrioritizer.makeQueueSubscription(e, t, (e) => {
            if ((o && (window.clearTimeout(o), (o = 0), (r = e)), e > 0)) {
              const t = (r - e) / Math.max(r, 1)
              s.notify(t)
            } else n()
          })
          return s.promise()
        }
        resetSweep(e) {
          this.enableHighRes(!1, e), this.resetPano(e), this.settings.reset()
        }
        availableResolution(e, t) {
          return this.qualityManager.availableResolution(e, t).nativePromise()
        }
        currentResolution() {
          return this.panoRenderer.getCurrentPanoResolution()
        }
        resetPano(e) {
          this.panoRenderer.resetRenderStatus(
            e,
            !1,
            !0,
            this.panoRenderer.panoQualityManager.getNavPanoSize()
          ),
            this.panoRenderer.clearAllQueuedUploadsForPano(e),
            this.panoRenderer.renderPanoTiles(e, null, !1, !1)
        }
      }
    },
    14209: (e, t, i) => {
      'use strict'
      i.d(t, { Z: () => r })
      var s = i(35026),
        n = i(38493)
      const r = class PanoRenderer {
        constructor(e, t) {
          ;(this.textureUsageCounter = {}),
            (this.model = e),
            (this.sweepList = t)
          const i = new n.Z((e) => e.id)
          for (let e of this.sweepList)
            e.isObservableProxy && (e = new s.ZP().copy(e)), i.add(e)
          this.sweepListMap = i
        }
        init() {}
        dispose() {}
        activate(e) {}
        deactivate(e) {}
        beforeRender() {}
        render() {}
        _activateSweep(e) {
          this.initTextureUsage(e)
        }
        _useTexture(e) {
          this.incrementTextureUsage(e)
        }
        freeTexture(e, t = !1) {
          t ? this.setTextureUsage(e, 0) : this.decrementTextureUsage(e)
        }
        initTextureUsage(e) {
          this.textureUsageCounter[e] || (this.textureUsageCounter[e] = 0)
        }
        setTextureUsage(e, t) {
          this.textureUsageCounter[e] = t
        }
        freeUnusedTextures() {
          for (const e of Object.keys(this.textureUsageCounter))
            0 === this.textureUsageCounter[e] && this.freeTexture(e)
        }
        incrementTextureUsage(e) {
          this.textureUsageCounter[e]++
        }
        decrementTextureUsage(e) {
          this.textureUsageCounter[e] > 0 && this.textureUsageCounter[e]--
        }
      }
    },
    69569: (e, t, i) => {
      'use strict'
      i.d(t, { Z: () => SweepPano })
      var s = i(47724)
      class SweepPano extends s.Y {
        constructor() {
          super(...arguments), (this.name = 'sweep-pano-base')
        }
        getRenderer() {
          return this.panoRenderer
        }
      }
    },
    30268: (e, t, i) => {
      'use strict'
      i.r(t), i.d(t, { default: () => SweepPanoSolid })
      var s = i(76463),
        n = i(14209)
      class SolidPanoRenderer extends n.Z {
        constructor(e, t) {
          super(e, t), (this.sweepLoader = new s.Z(e))
        }
        activateSweep(e) {
          super._activateSweep(e)
          const t = this.sweepListMap.get(e)
          return this.sweepLoader.load(t).then((e) => e)
        }
        useTexture(e) {
          const t = this.sweepLoader.useTexture(e)
          return t && super._useTexture(e), t
        }
        freeTexture(e, t = !1) {
          super.freeTexture(e, t),
            0 === this.textureUsageCounter[e] && this.sweepLoader.unload(e)
        }
        freeAllTextures(e) {
          this.sweepLoader.unloadAll(e)
        }
      }
      var r = i(44218),
        o = i(75892),
        a = i(69569),
        h = i(34369),
        l = i(64185)
      class SweepPanoSolid extends a.Z {
        constructor() {
          super(...arguments), (this.name = 'sweep-pano')
        }
        async init(e, t) {
          const i = (await t.getModule(r.default)).getSignedUrls(),
            s = (await t.market.waitForData(o.Z)).getSweepList()
          ;(this.panoRenderer = new SolidPanoRenderer(i, s)),
            t.addComponent(this, this.panoRenderer)
        }
        getRenderer() {
          return this.panoRenderer
        }
        resetSweep() {}
        async availableResolution() {
          return h.SL.STANDARD
        }
        async requestResolution() {
          return h.SL.STANDARD
        }
        waitForQueue() {
          return new l.Q().resolve().promise()
        }
        async enableZooming() {
          return !1
        }
      }
    },
    27166: (e, t, i) => {
      'use strict'
      i.r(t),
        i.d(t, {
          FAST_FORWARD_FACTOR: () => X,
          default: () => ToursControlsModule
        })
      var s = i(76701),
        n = i(77037),
        r = i(47724),
        o = i(94329),
        a = i(69941),
        h = i(35597),
        l = i(31278),
        d = i(91302),
        c = i(49340),
        u = i(81040),
        p = i(88727),
        g = i(88216),
        m = i(21479),
        w = i(8150),
        f = i(33874),
        v = i(59088),
        T = i(7170),
        y = i(19674),
        S = i(3506),
        P = i(3248),
        D = i(98828),
        b = i(20601),
        M = i(52599),
        x = i(10757)
      class TourDelayTransition {
        constructor(e) {
          ;(this.settingsData = e),
            (this.type = M.Aq.Delay),
            (this.toIndex = -1),
            (this.currentTransitionPromise = null),
            (this.cancelDelay = () => null)
        }
        get active() {
          return null !== this.currentTransitionPromise
        }
        get promise() {
          return this.currentTransitionPromise
            ? this.currentTransitionPromise
            : Promise.resolve()
        }
        async stop() {
          this.currentTransitionPromise &&
            (this.cancelDelay(), (this.currentTransitionPromise = null))
        }
        start() {
          if (this.active) throw Error('Transition already active')
          const e = (0, x.Ig)(
            TourTransitionFactory.getDelayDuration(this.settingsData)
          )
          return (
            (this.cancelDelay = () => {
              e.cancel()
            }),
            (this.currentTransitionPromise = e.promise.then(() => this.stop())),
            this
          )
        }
      }
      class TourZoomTransition {
        constructor(e, t, i) {
          ;(this.settingsData = e),
            (this.zoom = t),
            (this.stopZooming = i),
            (this.type = M.Aq.Zoom),
            (this.toIndex = -1),
            (this.currentTransitionPromise = null),
            (this.onStopRequested = () => Promise.resolve())
        }
        get active() {
          return null !== this.currentTransitionPromise
        }
        get promise() {
          return this.currentTransitionPromise
            ? this.currentTransitionPromise
            : Promise.resolve()
        }
        async stop() {
          this.currentTransitionPromise &&
            (await this.onStopRequested(),
            await this.promise,
            (this.currentTransitionPromise = null))
        }
        start() {
          if (this.active) throw Error('Transition already active')
          const e = TourTransitionFactory.getZoomDuration(this.settingsData)
          return (
            (this.currentTransitionPromise = this.zoom(e, -5e-4).then(() => {
              this.currentTransitionPromise = null
            })),
            (this.onStopRequested = async () => {
              await this.stopZooming()
            }),
            this
          )
        }
      }
      var I = i(2212),
        R = i(12216),
        C = i(68524)
      class TourPanTransition {
        constructor(e, t, i) {
          ;(this.settingsData = e),
            (this.rotate = t),
            (this.stopRotating = i),
            (this.type = M.Aq.Burns),
            (this.toIndex = -1),
            (this.currentTransitionPromise = null),
            (this.onStopRequested = () => Promise.resolve()),
            (this.getPanDirection = (e, t) => {
              let i = M.kw.Right
              if (
                e &&
                e.metadata.scanId &&
                e.metadata.cameraQuaternion &&
                e.metadata.cameraPosition &&
                t &&
                t.metadata.scanId &&
                t.metadata.cameraPosition &&
                t.metadata.cameraQuaternion
              ) {
                const s = R.f.FORWARD.clone().applyQuaternion(
                    e.metadata.cameraQuaternion
                  ),
                  n = t.metadata.cameraPosition,
                  r = e.metadata.cameraPosition
                let o = n.clone().sub(r).normalize()
                o.lengthSq() < C.Z.epsilon &&
                  (o = R.f.FORWARD.clone().applyQuaternion(
                    t.metadata.cameraQuaternion
                  )),
                  s.cross(o).y > 0 && (i = M.kw.Left)
              }
              return i
            })
        }
        get active() {
          return null !== this.currentTransitionPromise
        }
        get promise() {
          return this.currentTransitionPromise
            ? this.currentTransitionPromise
            : Promise.resolve()
        }
        async stop() {
          this.currentTransitionPromise &&
            (await this.onStopRequested(),
            await this.promise,
            (this.currentTransitionPromise = null))
        }
        start(e) {
          if (this.active) throw Error('Transition already active')
          if (!e) throw Error('Tour pan requires two snapshots')
          if (!e.snapshot || !e.nextSnapshot)
            return (this.currentTransitionPromise = Promise.resolve()), this
          const { deferred: t } = this.build(
            e.snapshot,
            e.nextSnapshot,
            e.panOverrides
          )
          return (
            (this.currentTransitionPromise = t.then(() => {
              this.currentTransitionPromise = null
            })),
            this
          )
        }
        build(e, t, i) {
          const { panDirection: s, panAngle: n } = i,
            r = TourTransitionFactory.getPanValues(this.settingsData, !1, s, n)
          let o = r.direction
          ;(void 0 !== o && o !== M.kw.Auto) ||
            (o = this.getPanDirection(e, t)),
            (this.onStopRequested = async () => {
              await this.stopRotating()
            })
          return {
            deferred: this.rotate(r.ms, new I.Vector2(o * r.radiansPerMs, 0))
          }
        }
      }
      var E = i(79437),
        L = i(64185)
      const F = 0.001,
        k = (e, t, i, s) => {
          const n = Math.min(e.distanceTo(t), 5),
            r = n * (1 / s) * 1e3
          let o = r
          const a = i / r
          if (a > F) {
            o += o * ((a - F) / F)
          }
          const h = Math.abs(
            e.clone().setX(0).setZ(0).distanceTo(t.clone().setX(0).setZ(0)) /
              Math.max(n, 1)
          )
          if (h > 0.1) {
            o *= 0.9 + 0.75 * h
          }
          return o
        }
      class TourDirectWalkingTransition {
        constructor(e, t, i, s, n, r) {
          ;(this.settingsData = e),
            (this.cameraPose = t),
            (this.moveToSweep = i),
            (this.updateTransitionSpeed = s),
            (this.setRestrictedSweeps = n),
            (this.generators = r),
            (this.toIndex = -1),
            (this.currentGenerator = null),
            (this.currentTransitionPromise = null),
            (this.type = M.Aq.Move)
        }
        get active() {
          return (
            null !== this.currentTransitionPromise ||
            null !== this.currentGenerator
          )
        }
        get promise() {
          return this.currentTransitionPromise
            ? this.currentTransitionPromise
            : Promise.resolve()
        }
        async stop() {
          this.currentTransitionPromise &&
            (await this.onStopRequested(),
            await this.promise,
            (this.currentTransitionPromise = null)),
            this.currentGenerator &&
              (this.generators.stopGenerator(this.currentGenerator),
              (this.currentGenerator = null))
        }
        start(e) {
          if (this.active) throw Error('Transition already active')
          const { generator: t, deferred: i } = this.build(
            e.path,
            e.orientations
          )
          return (
            this.generators.startGenerator(t),
            (this.currentGenerator = t),
            (this.currentTransitionPromise = i.nativePromise()),
            this
          )
        }
        build(e, t) {
          const i = new L.Q(),
            n = this
          let r = !1
          return (
            (this.onStopRequested = async () => {
              ;(r = !0), await this.updateTransitionSpeed(X)
            }),
            {
              generator: function* () {
                let o = 1
                for (; o < e.length && !r; ) {
                  const i = o - 1,
                    r = e[o],
                    a = r.position,
                    h = e[i],
                    d = t[o],
                    c = (0, y.zW)(n.cameraPose.rotation, d),
                    u = TourTransitionFactory.getTransitionSpeed(
                      n.settingsData
                    ),
                    p = k(h.position, a, c, u),
                    g = {
                      transitionType: l.n.Interpolate,
                      sweepId: r.id,
                      rotation: d,
                      transitionTime: p,
                      easing: E.vG
                    }
                  n.setRestrictedSweeps(e, i)
                  const m = n.moveToSweep(g)
                  yield new s.M8(m.nativePromise()), o++
                }
                n.setRestrictedSweeps(null),
                  i.resolve(),
                  (n.currentTransitionPromise = null),
                  n.stop()
              },
              deferred: i
            }
          )
        }
      }
      var A = i(27326)
      const N = new (i(88512).Z)('tours')
      class TourSmoothWalkingTransition {
        constructor(e, t, i, n, r, o, a, h, d) {
          ;(this.settingsData = e),
            (this.cameraPose = t),
            (this.cameraTransition = i),
            (this.sweepTransition = n),
            (this.sweepControl = r),
            (this.cameraControl = o),
            (this.generators = a),
            (this.setRestrictedSweeps = h),
            (this.getCurve = d),
            (this.type = M.Aq.Path),
            (this.toIndex = -1),
            (this.currentTransitionGenerator = null),
            (this.currentTransitionPromise = null),
            (this.canceling = !1),
            (this.buildTransition = (e, t) => {
              if (e.length <= 2)
                throw (
                  (N.debug(`invalid path: ${e}`),
                  new Error('smooth path requires more than 2 stops'))
                )
              const i = this,
                n = new L.Q()
              i.setRestrictedSweeps(e)
              const r = e.map((e) => e.position),
                o = i.getCurve(r),
                a = E.vG,
                h = E.Fs,
                d = E.to,
                c = TourTransitionFactory.getTransitionSpeed(i.settingsData),
                u = ((e, t, i) => {
                  let s = 0
                  for (let n = 0; n < e.length - 1; n++) {
                    const r = (0, y.zW)(t[n], t[n + 1])
                    s += k(e[n].position, e[n + 1].position, r, i)
                  }
                  return s
                })(e, t, c)
              N.debug(`path duration: ${u.toFixed(0)}ms, at speed: ${c}m/s`),
                i.cameraControl.beginExternalTransition()
              return {
                generator: function* () {
                  n.notify(0)
                  const r = new I.Vector3(),
                    p = new I.Quaternion()
                  let g = 0,
                    m = 0,
                    w = 0,
                    f = 1,
                    v = e[f].id
                  yield new s.M8(
                    i.sweepControl.activateSweepUnsafe({ sweepId: v })
                  ),
                    i.sweepControl.beginSweepTransition({
                      sweepId: v,
                      transitionTime: u,
                      internalProgress: !1
                    }),
                    e.length > 2 &&
                      i.sweepControl.activateSweepUnsafe({ sweepId: e[2].id })
                  let T = i.cameraPose.rotation.clone()
                  for (; g < u && !i.canceling; ) {
                    const l = g / u
                    w > 0 && (T = t[w].clone())
                    const c = t[f],
                      S = o.normalSourceDistances[w],
                      P = o.normalSourceDistances[f],
                      D = e[f]
                    if (((m = (0, y.et)(l, S, P, 0, 1)), m <= 1)) {
                      const e = d(m, 0, 1, 1)
                      i.sweepTransition.progress.modifyAnimation(e, 1, 0)
                      const t = h(m, 0, 1, 1)
                      p.copy(T).slerp(c, t)
                    }
                    l < 1 && r.copy(o.curve.getPointAt(a(l, 0, 1, 1))),
                      i.cameraControl.updateCameraPosition(r),
                      i.cameraControl.updateCameraRotation(p),
                      l >= P &&
                        (i.sweepControl.endSweepTransition({ sweepId: D.id }),
                        w++,
                        f++,
                        (v = e[w + 1].id),
                        yield new s.M8(
                          i.sweepControl.activateSweepUnsafe({ sweepId: v })
                        ),
                        i.sweepControl.beginSweepTransition({
                          sweepId: v,
                          transitionTime: u,
                          internalProgress: !1
                        }),
                        e.length > w + 2 &&
                          i.sweepControl.activateSweepUnsafe({
                            sweepId: e[w + 2].id
                          })),
                      n.notify(l),
                      (g = Date.now() - i.cameraTransition.startTime),
                      yield new s.Jj()
                  }
                  if ((i.cameraControl.endExternalTransition(), i.canceling)) {
                    i.canceling = !1
                    const t = e[f].position,
                      n = k(i.cameraPose.position, t, 0, c),
                      r = i.cameraControl.moveTo({
                        transitionTime: n / X,
                        transitionType: l.n.Interpolate,
                        pose: { position: t }
                      })
                    r.progress((e) => {
                      const t = (0, y.et)(e, 0, 1, m, 1)
                      i.sweepTransition.progress.modifyAnimation(t, 1, 0)
                    }),
                      yield new s.M8(r.nativePromise())
                  }
                  i.sweepControl.endSweepTransition({ sweepId: v }),
                    i.setRestrictedSweeps(null),
                    n.notify(1),
                    n.resolve()
                },
                deferred: n
              }
            })
        }
        get active() {
          return (
            null !== this.currentTransitionPromise ||
            null !== this.currentTransitionGenerator
          )
        }
        get promise() {
          return this.currentTransitionPromise
            ? this.currentTransitionPromise
            : Promise.resolve()
        }
        async stop() {
          ;(this.canceling = !0),
            this.currentTransitionPromise &&
              (await this.promise, (this.currentTransitionPromise = null)),
            this.currentTransitionGenerator &&
              (this.generators.stopGenerator(this.currentTransitionGenerator),
              (this.currentTransitionGenerator = null))
        }
        start(e) {
          if (
            (N.debug(
              `starting smooth transition with ${e.path.length - 1} stops`
            ),
            this.active)
          )
            throw Error('Transition already active')
          this.canceling = !1
          const { generator: t, deferred: i } = this.buildTransition(
            e.path,
            e.orientations
          )
          return (
            this.generators.startGenerator(t),
            (this.currentTransitionGenerator = t),
            (this.currentTransitionPromise = i.nativePromise().then(() => {
              ;(this.currentTransitionPromise = null),
                (this.currentTransitionGenerator = null)
            })),
            this
          )
        }
      }
      var O = i(56656),
        G = i(75892),
        z = i(77719),
        V = i(20021),
        U = i(13988)
      class TourDefaultTransition {
        constructor(e, t, i, s, n, r, o, a) {
          ;(this.settingsData = e),
            (this.cameraPose = t),
            (this.viewmodeData = i),
            (this.cameraControl = s),
            (this.sweepControl = n),
            (this.switchToMode = r),
            (this.setRestrictedSweeps = o),
            (this.generators = a),
            (this.toIndex = -1),
            (this.type = M.Aq.Move),
            (this.currentTransitionPromise = null),
            (this.onStopRequested = () => Promise.resolve())
        }
        get active() {
          return null !== this.currentTransitionPromise
        }
        get promise() {
          return this.currentTransitionPromise
            ? this.currentTransitionPromise
            : Promise.resolve()
        }
        async stop() {
          this.currentTransitionPromise &&
            (await this.onStopRequested(),
            await this.promise,
            (this.currentTransitionPromise = null))
        }
        start(e) {
          if (this.active) throw Error('Transition already active')
          if (!e.snapshot)
            return (this.currentTransitionPromise = Promise.resolve()), this
          const { deferred: t } = this.build(
            e.snapshot,
            e.currentSweep,
            e.transitionType
          )
          return (
            (this.currentTransitionPromise = t.then(() => {
              this.currentTransitionPromise = null
            })),
            this
          )
        }
        build(e, t, i) {
          let s = Promise.resolve()
          const n = e.metadata.cameraMode,
            r = e.metadata.cameraQuaternion,
            o = e.metadata.scanId,
            a = this.cameraPose.rotation,
            h = (0, y.zW)(a, r),
            l = e.metadata.cameraPosition,
            d = !e.is360,
            c = {
              position: l,
              rotation: r,
              sweepID: o,
              zoom: e.metadata.orthoZoom
            }
          if (n !== this.viewmodeData.currentMode) {
            const e = TourTransitionFactory.getOtherModeTransitionTime(
              this.settingsData,
              h,
              i
            )
            s = this.switchToMode(n, i, c, e)
          } else {
            if (!!o && this.viewmodeData.isInside()) {
              if (!t || o !== t) {
                const e = TourTransitionFactory.getTransitionTime(
                  this.settingsData
                )
                s = this.standardTransitionSweepMovePromise(c, o, d, e)
              } else {
                const e = TourTransitionFactory.getSamePanoTransitionTime(
                  this.settingsData,
                  h
                )
                s = this.standardTransitionSameSweepRotationPromise(c, h, e)
              }
            } else
              s = this.cameraControl
                .moveTo({
                  transitionType: i,
                  pose: c,
                  transitionTime:
                    TourTransitionFactory.getOtherModeTransitionTime(
                      this.settingsData,
                      h,
                      i
                    )
                })
                .nativePromise()
          }
          return { deferred: s }
        }
        standardTransitionSameSweepRotationPromise(e, t, i) {
          if (!e.rotation)
            throw Error('Rotation transition requires a rotation')
          return t < 0.01
            ? Promise.resolve()
            : (this.setRestrictedSweeps(null),
              this.cameraControl
                .moveTo({
                  transitionType: l.n.Interpolate,
                  pose: { rotation: e.rotation },
                  transitionTime: i
                })
                .nativePromise())
        }
        standardTransitionSweepMovePromise(e, t, i, n) {
          if (!e.position) throw Error('Push transition requires a position')
          const r = e.position
              .clone()
              .sub(this.cameraPose.position)
              .normalize(),
            o = this.cameraPose.position.clone().add(r.multiplyScalar(0.15)),
            a = new L.Q()
          this.setRestrictedSweeps(null)
          const h = this
          return (
            this.generators.startGenerator(function* () {
              yield new s.M8(h.sweepControl.activateSweepUnsafe({ sweepId: t }))
              const r = new I.Vector3(),
                d = h.cameraPose.position.clone(),
                c = Date.now()
              let u,
                p = 0,
                g = !1,
                m = !1
              for (; p < n; ) {
                const a = (0, E.FG)(p, 0, p / n, n)
                i && h.cameraControl.updateCameraPosition(r.copy(d).lerp(o, a)),
                  a >= 0.3 &&
                    !m &&
                    ((u = h.cameraControl
                      .moveTo({
                        transitionType: l.n.FadeToBlack,
                        pose: e,
                        transitionTime: n,
                        blackoutTime: 0.5 * n
                      })
                      .progress((e) => {
                        e >= 0.5 &&
                          !g &&
                          (h.sweepControl.instantSweepTransition(t), (g = !0))
                      })),
                    (m = !0)),
                  yield new s.Jj(),
                  (p = Date.now() - c)
              }
              u && (yield new s.M8(u.nativePromise())), a.resolve()
            }),
            a.nativePromise()
          )
        }
      }
      class TourInstantTransition {
        constructor(e, t, i, s) {
          ;(this.moveToSweep = e),
            (this.viewmodeData = t),
            (this.cameraControl = i),
            (this.switchToMode = s),
            (this.toIndex = -1),
            (this.type = M.Aq.Move),
            (this.currentTransitionPromise = null),
            (this.onStopRequested = () => Promise.resolve())
        }
        get active() {
          return null !== this.currentTransitionPromise
        }
        get promise() {
          return this.currentTransitionPromise
            ? this.currentTransitionPromise
            : Promise.resolve()
        }
        async stop() {
          this.currentTransitionPromise &&
            (await this.onStopRequested(),
            await this.promise,
            (this.currentTransitionPromise = null))
        }
        start(e) {
          if (this.active) throw Error('Transition already active')
          if (!e.snapshot)
            return (this.currentTransitionPromise = Promise.resolve()), this
          const { deferred: t } = this.build(e.snapshot, e.currentSweep)
          return (
            (this.currentTransitionPromise = t.then(() => {
              this.currentTransitionPromise = null
            })),
            this
          )
        }
        build(e, t) {
          let i = Promise.resolve()
          const s = e.metadata.cameraMode,
            n = e.metadata.cameraQuaternion,
            r = e.metadata.scanId,
            o = {
              position: e.metadata.cameraPosition,
              rotation: n,
              sweepID: r,
              zoom: e.metadata.orthoZoom
            },
            a = s !== this.viewmodeData.currentMode,
            h = !!r && this.viewmodeData.isInside()
          if (a) i = this.switchToMode(s, l.n.Instant, o)
          else if (h) {
            const e = { transitionType: l.n.Instant, sweepId: r, rotation: n }
            i = this.moveToSweep(e).nativePromise()
          } else
            i = this.cameraControl
              .moveTo({ transitionType: l.n.Instant, pose: o })
              .nativePromise()
          return { deferred: i }
        }
      }
      var B = i(93263),
        Q = i(2725)
      class TourFloorChangeTransition {
        constructor(e, t) {
          ;(this.issueCommand = e),
            (this.currentFloorId = t),
            (this.type = M.Aq.FloorChange),
            (this.toIndex = -1),
            (this.currentTransitionPromise = null),
            (this.onStopRequested = () => Promise.resolve())
        }
        get active() {
          return null !== this.currentTransitionPromise
        }
        get promise() {
          return this.currentTransitionPromise
            ? this.currentTransitionPromise
            : Promise.resolve()
        }
        async stop() {
          this.currentTransitionPromise &&
            (await this.onStopRequested(),
            await this.promise,
            (this.currentTransitionPromise = null))
        }
        start(e) {
          if (this.active) throw Error('Transition already active')
          let t = Promise.resolve()
          const i = e.targetSnapshot.metadata.floorId,
            s = i !== this.currentFloorId(),
            n = e.targetSnapshot.metadata.cameraMode
          return (
            !(0, o.Bw)(n) &&
              n !== o.Ey.Outdoor &&
              s &&
              (t = this.issueCommand(new Q.Vw(i, !0))),
            (this.currentTransitionPromise = t.then(() => {
              this.currentTransitionPromise = null
            })),
            this
          )
        }
      }
      class TourDollhousePanTransition {
        constructor(e, t, i) {
          ;(this.settingsData = e),
            (this.rotate = t),
            (this.stopRotating = i),
            (this.type = M.Aq.Burns),
            (this.toIndex = -1),
            (this.currentTransitionPromise = null),
            (this.onStopRequested = () => Promise.resolve())
        }
        get active() {
          return null !== this.currentTransitionPromise
        }
        get promise() {
          return this.currentTransitionPromise
            ? this.currentTransitionPromise
            : Promise.resolve()
        }
        async stop() {
          this.currentTransitionPromise &&
            (await this.onStopRequested(),
            await this.promise,
            (this.currentTransitionPromise = null))
        }
        start(e) {
          if (this.active) throw Error('Transition already active')
          if (!e.snapshot || !e.nextSnapshot)
            return (this.currentTransitionPromise = Promise.resolve()), this
          const { deferred: t } = this.build(
            e.snapshot,
            e.nextSnapshot,
            e.panOverrides
          )
          return (
            (this.currentTransitionPromise = t.then(() => {
              this.currentTransitionPromise = null
            })),
            this
          )
        }
        build(e, t, i) {
          const { panDirection: s, panAngle: n } = i,
            r = TourTransitionFactory.getPanValues(this.settingsData, !0, s, n)
          let o = -1 * r.radiansPerMs
          const a = r.direction
          if (void 0 !== a && a !== M.kw.Auto) o *= a
          else if (
            e &&
            e.metadata.cameraQuaternion &&
            t &&
            t.metadata.cameraQuaternion
          ) {
            const i = R.f.FORWARD.clone().applyQuaternion(
                e.metadata.cameraQuaternion
              ),
              s = R.f.FORWARD.clone().applyQuaternion(
                t.metadata.cameraQuaternion
              ),
              n = Math.sign(i.cross(s).y)
            o = 0 !== n ? o * n : o
          }
          this.onStopRequested = async () => {
            await this.stopRotating()
          }
          return { deferred: this.rotate(r.ms, new I.Vector2(o, 0)) }
        }
      }
      class TourPanTransitionLegacy {
        constructor(e, t, i, s, n) {
          ;(this.settingsData = e),
            (this.cameraPose = t),
            (this.rotate = i),
            (this.stopRotating = s),
            (this.getCurve = n),
            (this.type = M.Aq.Burns),
            (this.toIndex = -1),
            (this.currentTransitionPromise = null),
            (this.onStopRequested = () => Promise.resolve())
        }
        get active() {
          return null !== this.currentTransitionPromise
        }
        get promise() {
          return this.currentTransitionPromise
            ? this.currentTransitionPromise
            : Promise.resolve()
        }
        async stop() {
          this.currentTransitionPromise &&
            (await this.onStopRequested(),
            await this.promise,
            (this.currentTransitionPromise = null))
        }
        start(e) {
          if (this.active) throw Error('Transition already active')
          const { deferred: t } = this.build(
            e.path,
            e.snapshot,
            e.nextSnapshot,
            e.panOverrides
          )
          return (
            (this.currentTransitionPromise = t.then(() => {
              this.currentTransitionPromise = null
            })),
            this
          )
        }
        build(e, t, i, s) {
          this.onStopRequested = async () => {
            await this.stopRotating()
          }
          const { panDirection: n, panAngle: r } = s,
            a = TourTransitionFactory.getPanValues(this.settingsData, !1, n, r),
            h = a.direction
          let l = a.radiansPerMs
          if (void 0 !== h && h !== M.kw.Auto) l *= h
          else if (e) {
            const t = this.cameraPose.position.clone().setY(0),
              i = e.map((e) => e.position),
              s = this.getCurve(i)
                .curve.getPointAt(0.1)
                .setY(0)
                .clone()
                .sub(t)
                .normalize(),
              n = R.f.FORWARD.clone().applyQuaternion(this.cameraPose.rotation),
              r = Math.sign(n.cross(s).y)
            l = 0 !== r ? l * r : l
          } else if (i && t) {
            if (
              (!(0, o.Bw)(t.metadata.cameraMode) && (l = -l),
              t.metadata.scanId === i.metadata.scanId)
            ) {
              const e = R.f.FORWARD.clone().applyQuaternion(
                  this.cameraPose.rotation
                ),
                t = R.f.FORWARD.clone().applyQuaternion(
                  i.metadata.cameraQuaternion
                ),
                s = Math.sign(e.cross(t).y)
              l = 0 !== s ? l * s : l
            }
          }
          return { deferred: this.rotate(a.ms, new I.Vector2(l, 0)) }
        }
      }
      const _ = {
        sharpTurnDotThreshold: 0.65,
        directionWeightFactorStd: 0.75,
        directionWeightFactorSharp: 0.2,
        positionalWeightFactorStd: 0.4,
        positionalWeightFactorSharp: 0.2,
        finalWalkingNodeDirectionWeight: 5,
        lookAheadNodes: 3
      }
      class OrientationHelper {
        constructor(e = _) {
          this.settings = e
        }
        getOrientationsForPath(e, t) {
          const i = []
          for (let s = 0; s < e.length; s++) {
            const n = new I.Vector3()
            this.getLookVectorsForPathNode(e, s, t, n)
            const r = new I.Matrix4().lookAt(e[s], n, R.f.UP)
            i[s] = new I.Quaternion().setFromRotationMatrix(r)
          }
          return i.push(t), i
        }
        getLookVectorsForPathNode(e, t, i, s) {
          const n = new I.Vector3(),
            r = new I.Vector3(),
            o = new I.Vector3(),
            a = new I.Vector3(),
            h = e.length
          if (t >= h) return !1
          let l = 1,
            d = 1
          const c = new I.Vector3()
          let u
          for (let s = t; s < t + this.settings.lookAheadNodes && s < h; s++) {
            if (
              ((u = e[s]),
              this.getOrientationForPathNode(e, s, i, o),
              s === t && n.copy(o),
              s > t)
            ) {
              const e = n.dot(o) < this.settings.sharpTurnDotThreshold
              ;(l *= e
                ? this.settings.directionWeightFactorSharp
                : this.settings.directionWeightFactorStd),
                (d *= e
                  ? this.settings.positionalWeightFactorSharp
                  : this.settings.positionalWeightFactorStd)
            }
            s === h - 1 &&
              ((l = this.settings.finalWalkingNodeDirectionWeight), (d = 1)),
              c.copy(o),
              o.multiplyScalar(l),
              r.add(o),
              a.lerp(u, d)
          }
          return r.normalize(), s.copy(a), s.add(r), !0
        }
        getOrientationForPathNode(e, t, i, s) {
          if (t >= e.length) return !1
          if (t === e.length - 1) s.copy(R.f.FORWARD).applyQuaternion(i)
          else {
            const i = e[t],
              n = e[t + 1]
            s.copy(n).sub(i)
          }
          return s.normalize(), !0
        }
      }
      class TourTransitionFactory {
        constructor(e, t, i, s, r) {
          ;(this.engine = e),
            (this.tourData = t),
            (this.cameraData = i),
            (this.settingsData = s),
            (this.viewmodeData = r),
            (this.init = async () => {
              ;(this.sweepModule = await this.engine.getModule(O.default)),
                (this.sweepData = await this.engine.market.waitForData(G.Z)),
                (this.cameraModule = await this.engine.getModule(z.default)),
                (this.pathModule = await this.engine.getModule(V.default)),
                (this.floorsViewData = await this.engine.market.waitForData(
                  A.c
                )),
                (this.commonControlsModule = await this.engine.getModule(
                  U.default
                )),
                (this.viewmodeModule = await this.engine.getModule(B.default)),
                (this.smoothWalkingTransition = new TourSmoothWalkingTransition(
                  this.settingsData,
                  this.cameraData.pose,
                  this.cameraData.transition,
                  this.sweepData.transition,
                  this.sweepModule,
                  this.cameraModule,
                  this.engine,
                  this.pathModule.setRestrictedSweeps.bind(this.pathModule),
                  this.pathModule.getCurveForPath.bind(this.pathModule)
                )),
                (this.directWalkingTransition = new TourDirectWalkingTransition(
                  this.settingsData,
                  this.cameraData.pose,
                  this.sweepModule.moveToSweep.bind(this.sweepModule),
                  this.cameraModule.updateTransitionSpeed.bind(
                    this.cameraModule
                  ),
                  this.pathModule.setRestrictedSweeps.bind(this.pathModule),
                  this.engine
                )),
                (this.instantTransition = new TourInstantTransition(
                  this.sweepModule.moveToSweep.bind(this.sweepModule),
                  this.viewmodeData,
                  this.cameraModule,
                  this.viewmodeModule.switchToMode.bind(this.viewmodeModule)
                )),
                (this.panTransition = new TourPanTransition(
                  this.settingsData,
                  this.commonControlsModule.startRotateTransition.bind(
                    this.commonControlsModule
                  ),
                  this.commonControlsModule.stop.bind(this.commonControlsModule)
                )),
                (this.panLegacyTransition = new TourPanTransitionLegacy(
                  this.settingsData,
                  this.cameraData.pose,
                  this.commonControlsModule.startRotateTransition.bind(
                    this.commonControlsModule
                  ),
                  this.commonControlsModule.stop.bind(
                    this.commonControlsModule
                  ),
                  this.pathModule.getCurveForPath.bind(this.pathModule)
                )),
                (this.panDollhouseTransition = new TourDollhousePanTransition(
                  this.settingsData,
                  this.commonControlsModule.startRotateTransition.bind(
                    this.commonControlsModule
                  ),
                  this.commonControlsModule.stop.bind(this.commonControlsModule)
                )),
                (this.defaultTransition = new TourDefaultTransition(
                  this.settingsData,
                  this.cameraData.pose,
                  this.viewmodeData,
                  this.cameraModule,
                  this.sweepModule,
                  this.viewmodeModule.switchToMode.bind(this.viewmodeModule),
                  this.pathModule.setRestrictedSweeps.bind(this.pathModule),
                  this.engine
                )),
                (this.zoomTransition = new TourZoomTransition(
                  this.settingsData,
                  this.commonControlsModule.startZoomTransition.bind(
                    this.commonControlsModule
                  ),
                  this.commonControlsModule.stop.bind(this.commonControlsModule)
                )),
                (this.floorChangeTransition = new TourFloorChangeTransition(
                  this.engine.commandBinder.issueCommand.bind(
                    this.engine.commandBinder
                  ),
                  () => this.floorsViewData.currentFloorId
                )),
                (this.delayTransition = new TourDelayTransition(
                  this.settingsData
                )),
                (this.nopTransition = {
                  active: !1,
                  type: M.Aq.Nop,
                  promise: Promise.resolve(),
                  stop: () => Promise.resolve(),
                  toIndex: -1
                }),
                (this.pathOrientHelper = new OrientationHelper())
            }),
            (this.getValidWalkingPath = (e) => {
              const t = e.metadata.scanId,
                i = this.sweepData.currentSweep,
                s = this.tourData.getTourCurrentSnapshotIndex()
              let r = null
              if (s >= 0) {
                const e = this.tourData.getTourSnapshotSid(s)
                r = this.tourData.getSnapshot(e)
              }
              if (
                this.viewmodeData.currentMode !== o.Ey.Panorama ||
                !i ||
                !t ||
                t === i ||
                e.is360 ||
                !r ||
                r.is360
              )
                return null
              const a =
                this.pathModule.findShortestPath(
                  i,
                  t,
                  n.Xd.walkingTourIncludeExtraPanosDistance,
                  n.Xd.walkingStageMinimumDistance,
                  n.Xd.maxWalkingSweepsBetweenSnapshots
                ) || []
              return 0 === a.length ? null : a
            })
        }
        static getPanDegrees(e, t) {
          let i
          return (
            (i = n.Xd.panAtSnapshot
              ? -1 !== (0, D.h)('sspa', -1)
                ? n.Xd.snapshotPanAngle
                : void 0 !== t
                ? t
                : e.tryGetProperty(P.gx.PanAngle, n.BA)
              : 0),
            Math.max(i, 0)
          )
        }
        static getPanRadiansPerMs(e, t, i) {
          if (-1 !== (0, D.h)('st', -1))
            return n.Xd.snapshotPanZoomDuration > 0
              ? i / n.Xd.snapshotPanZoomDuration
              : 0
          const s = t
            ? e.tryGetProperty(P.gx.DollhousePanSpeed, n.su)
            : e.tryGetProperty(P.gx.PanSpeed, n.pn)
          return (0, b.DA)(s)
        }
        getFloorTransition(e) {
          const t = this.tourData.getTourSnapshotSid(e),
            i = this.tourData.getSnapshot(t)
          if (!i) return this.nopTransition
          return this.floorChangeTransition.start({ targetSnapshot: i })
        }
        getMainTransition(e, t) {
          const i = this.tourData.getTourSnapshotSid(e),
            s = this.tourData.getSnapshot(i)
          if (!s) return this.nopTransition
          let n = null
          if (t === l.n.Interpolate) {
            const e = s.metadata.cameraQuaternion,
              t = this.getValidWalkingPath(s)
            if (t) {
              const i = t.map((e) => e.position),
                s = this.pathOrientHelper.getOrientationsForPath(i, (0, y.Z)(e))
              n =
                t.length > 2
                  ? this.smoothWalkingTransition.start({
                      path: t,
                      orientations: s
                    })
                  : this.directWalkingTransition.start({
                      path: t,
                      orientations: s
                    })
            }
          } else if (t === l.n.Instant) {
            const e = this.sweepData.currentSweep
            n = this.instantTransition.start({ snapshot: s, currentSweep: e })
          }
          if (!n) {
            const e = this.sweepData.currentSweep
            n = this.defaultTransition.start({
              snapshot: s,
              currentSweep: e,
              transitionType: t
            })
          }
          return n
        }
        getBurnsTransition(e, t) {
          const i = this.tourData.getTourSnapshotSid(e),
            s = (e + 1) % this.tourData.getSnapshotCount(),
            n = this.tourData.getTourSnapshotSid(s),
            r = this.tourData.getHighlightDescription(i),
            o = {}
          r.reelEntry &&
            r.reelEntry.overrides &&
            ((o.panDirection = r.reelEntry.overrides.panDirection),
            (o.panAngle = r.reelEntry.overrides.panAngle))
          const a = this.tourData.getSnapshot(n)
          let h = this.nopTransition
          switch (t) {
            case M.BZ.Pan:
              if (a) {
                const e = this.getValidWalkingPath(a)
                h = this.panLegacyTransition.start({
                  path: e,
                  snapshot: r.snapshot,
                  nextSnapshot: a,
                  panOverrides: o
                })
              }
              h === this.nopTransition &&
                (h = this.panTransition.start({
                  snapshot: r.snapshot,
                  nextSnapshot: a,
                  panOverrides: o
                }))
              break
            case M.BZ.PanDollhouse:
              h = this.panDollhouseTransition.start({
                snapshot: r.snapshot,
                nextSnapshot: a,
                panOverrides: o
              })
              break
            case M.BZ.Zoom:
              h = this.zoomTransition.start()
              break
            case M.BZ.Delay:
              h = this.delayTransition.start()
              break
            case M.BZ.None:
              h = this.nopTransition
              break
            default:
              throw Error('unhandled TourBurnsStyle')
          }
          return h
        }
      }
      ;(TourTransitionFactory.useDelayTransition = (e, t, i) =>
        !n.Xd.panAtSnapshot ||
        (t !== M.BZ.Zoom && 0 === TourTransitionFactory.getPanDegrees(e, i))),
        (TourTransitionFactory.getPanDirection = (e, t) =>
          void 0 !== t ? t : e.tryGetProperty(P.gx.PanDirection, S.y6)),
        (TourTransitionFactory.getDelayDuration = (e) =>
          -1 !== (0, D.h)('st', -1) || 0 === (0, D.h)('kb', -1)
            ? n.Xd.snapshotPanZoomDuration
            : n.mS),
        (TourTransitionFactory.getZoomDuration = (e) =>
          -1 !== (0, D.h)('st', -1)
            ? n.Xd.snapshotPanZoomDuration
            : e.tryGetProperty(P.gx.ZoomDuration, n._c)),
        (TourTransitionFactory.getPanValues = (e, t, i, s) => {
          const r = TourTransitionFactory.getPanDirection(e, i),
            o = TourTransitionFactory.getPanDegrees(e, s),
            a = (0, T.Id)(o),
            h = TourTransitionFactory.getPanRadiansPerMs(e, t, a)
          let l = h > 0 ? a / h : 0
          return (
            t && void 0 === s && (l = n.Xd.snapshotPanZoomDuration),
            { degrees: o, radiansPerMs: h, ms: l, direction: r }
          )
        }),
        (TourTransitionFactory.getTransitionSpeed = (e) => {
          if (-1 !== (0, D.h)('wts', -1)) return e.tryGetProperty(n.EU, n.Im)
          const t = e.tryGetProperty(P.gx.TransitionSpeed, n.Mk)
          return (0, b.mf)(t / 1e3)
        }),
        (TourTransitionFactory.getTransitionTime = (e) => {
          const t = e.tryGetProperty(P.gx.TransitionTime, n.mL)
          return Math.min(Math.max(n.eu, t), n.NY)
        }),
        (TourTransitionFactory.getOtherModeTransitionTime = (e, t, i) => {
          if (i === l.n.FadeToBlack) {
            return TourTransitionFactory.getTransitionTime(e) + n.HJ
          }
          let s = n.Cp,
            r = n.f7
          if (-1 === (0, D.h)('wts', -1)) {
            const t = 1e3 * TourTransitionFactory.getTransitionSpeed(e)
            ;(s = Math.sqrt(2 * (t - n.Pv)) + 45), t !== n.Mk && (r = n._D)
          }
          const o = (1e3 * t) / (T.Ue * s)
          return Math.max(o, r)
        }),
        (TourTransitionFactory.getSamePanoTransitionTime = (e, t) => {
          const i = e.tryGetProperty(P.gx.PanSpeed, n.pn)
          if (i === n.pn) return Math.max((1e3 * t) / (T.Ue * n.O2), n.gS)
          {
            const e = (0, y.dS)(i, n.z$, n.b_, n.rM, n.z8),
              s = (0, b.DA)(e)
            return s > 0 ? t / s : 0
          }
        })
      var H = i(37381),
        j = i(96216),
        q = i(80191),
        Z = i(96909)
      const X = 5
      class ToursControlsModule extends r.Y {
        constructor() {
          super(...arguments),
            (this.name = 'tours-controls'),
            (this.getBurnsStyleForSnapshot = (e, t, i) => {
              const s = e.getTourSnapshotSid(t),
                n = e.getHighlightDescription(s),
                r = e.getSnapshotCount()
              if (!n || !n.snapshot) return M.BZ.None
              const a = n.snapshot.metadata.cameraMode,
                h = t === r - 1,
                l =
                  n.reelEntry &&
                  n.reelEntry.overrides &&
                  n.reelEntry.overrides.panDirection,
                d =
                  a === o.Ey.Dollhouse
                    ? M.BZ.PanDollhouse
                    : a === o.Ey.Floorplan
                    ? M.BZ.Zoom
                    : M.BZ.Pan
              return TourTransitionFactory.useDelayTransition(
                this.settingsData,
                d,
                i
              )
                ? M.BZ.Delay
                : h && void 0 !== l
                ? d
                : h
                ? M.BZ.None
                : d
            }),
            (this.canChangeTourLocation = () => {
              const e = this.data.getTourState(),
                t = this.data.isTourTransitionActive(),
                i = this.cameraData.canTransition()
              return (
                e === a.Vs.Inactive &&
                !t &&
                !(
                  this.viewmodeData.transition &&
                  this.viewmodeData.transition.active
                ) &&
                i
              )
            })
        }
        async init(e, t) {
          ;(this.engine = t),
            (this.cameraData = await t.market.waitForData(v.M_)),
            (this.viewmodeData = await t.market.waitForData(h.O)),
            (this.settingsData = await t.market.waitForData(f.e)),
            (this.data = await t.market.waitForData(a.k3)),
            t.getModuleBySymbol(Z.y.INPUT).then((e) => {
              e.registerHandler(c.er, () => {
                this.handleTourInputInterrupt()
              }),
                e.registerHandler(u.a, () => {
                  this.handleTourInputInterrupt()
                }),
                e.registerHandler(p.e, (e) => {
                  e.state === g.M.DOWN && this.handleTourInputInterrupt()
                })
            }),
            (this.transitionFactory = new TourTransitionFactory(
              t,
              this.data,
              this.cameraData,
              this.settingsData,
              this.viewmodeData
            )),
            await this.transitionFactory.init(),
            this.setupAutoPlay(t),
            this.bindings.push(
              t.commandBinder.addBinding(j.TH, async (e) =>
                this.startTour(e.index, e.steps, e.loop)
              )
            ),
            this.bindings.push(
              t.commandBinder.addBinding(j.vy, async () => this.stopTour())
            ),
            this.bindings.push(
              t.commandBinder.addBinding(j.rU, async (e) =>
                this.tourGoTo(e.index, e.instant ? l.n.Instant : void 0)
              )
            ),
            this.bindings.push(
              t.commandBinder.addBinding(j.HW, async (e) =>
                e.forward
                  ? this.tourGoNext(e.instant)
                  : this.tourGoPrevious(e.instant)
              )
            ),
            this.bindings.push(
              t.subscribe(d.Vx, () => {
                this.data.setTourTransitionToIndex(-1)
              }),
              t.subscribe(d.NR, () => {
                this.data.setTourTransitionToIndex(-1)
              })
            )
        }
        handleTourInputInterrupt() {
          this.data.getTourState() !== a.Vs.Inactive && this.stopTour()
        }
        canTourProceed(e, t, i) {
          const s = this.data.getSnapshotCount()
          if (0 === s || 0 === i || this.data.getTourState() !== a.Vs.Inactive)
            return !1
          if (void 0 !== t) {
            if (t < -1) return !1
            if (!0 !== e && t > s - 1) return !1
          }
          return !0
        }
        shouldTourContinue(e, t, i, s) {
          return void 0 !== s ? i < s : t < e - 1
        }
        startTour(e, t, i) {
          if (!this.canChangeTourLocation())
            throw new q.Y(
              'Cannot start tour at this time, another transition is active'
            )
          const n = void 0 !== i ? i : this.data.isLooping()
          if (!this.canTourProceed(n, e, t)) return
          const r = this.data.getSnapshotCount(),
            o = this.data.getTourCurrentSnapshotIndex()
          let h,
            l = 0
          h = void 0 !== e ? e - 1 : o >= r - 1 ? -1 : o
          const c = this.settingsData.tryGetProperty(H.YS, null)
          this.settingsData.setProperty(H.YS, null)
          const u = this
          ;(this.tourGenerator = function* () {
            for (; u.shouldTourContinue(r, h, l, t); ) {
              const e = h + 1,
                t = u.composeTourTransition(e)
              yield new s.M8(t), (h = e), h === r - 1 && n && (h = -1), l++
            }
            u.stopTour(), u.settingsData.setProperty(H.YS, c)
          }),
            this.engine.startGenerator(this.tourGenerator),
            this.data.setTourState(a.Vs.Active),
            (this.data.tourEnded = !1),
            (this.data.tourPlaying = !0),
            this.engine.broadcast(new d.oR())
        }
        async composeTourTransition(e, t, i) {
          const s = this.data.getTourSnapshotSid(e),
            n = this.data.getHighlightDescription(s)
          if (!n.snapshot)
            throw Error(`Highlight not found for reel index ${e}`)
          let r = this.settingsData.tryGetProperty(S.gj, l.n.Interpolate)
          const h = n.snapshot.metadata.cameraMode,
            c = h === o.Ey.Dollhouse || h === o.Ey.Floorplan,
            u = (0, o.Bw)(h),
            p = !this.viewmodeData.isInside() && u,
            g = this.viewmodeData.isInside() && c,
            m = !this.viewmodeData.isInside() && c,
            w = this.viewmodeData.isInside() && u
          let f = null
          ;(p || g || m) && (r = l.n.Interpolate),
            w && 0 === e && (r = l.n.FadeToBlack),
            n.reelEntry &&
              n.reelEntry.overrides &&
              (void 0 !== n.reelEntry.overrides.transitionType &&
                (r = n.reelEntry.overrides.transitionType),
              void 0 !== n.reelEntry.overrides.panAngle &&
                (f = n.reelEntry.overrides.panAngle)),
            void 0 !== i && (r = i),
            this.data.setTourTransitionToIndex(e),
            this.engine.broadcast(new d.dW())
          const v = this.transitionFactory.getFloorTransition(e)
          if (
            (this.data.useTransition(v),
            await v.promise,
            this.data.getTourState() === a.Vs.StopScheduled)
          )
            return
          const T = this.transitionFactory.getMainTransition(e, r)
          if (
            (this.data.useTransition(T),
            await T.promise,
            this.data.setTourCurrentSnapshotByIndex(e),
            this.engine.broadcast(new d.Vx(e)),
            this.data.getTourState() === a.Vs.StopScheduled)
          )
            return
          const y =
              t ||
              this.getBurnsStyleForSnapshot(
                this.data,
                e,
                null !== f ? f : void 0
              ),
            P = this.transitionFactory.getBurnsTransition(e, y)
          this.data.useTransition(P), await P.promise
        }
        async stopTour() {
          this.data.getTourState() === a.Vs.Active &&
            (this.data.setTourState(a.Vs.StopScheduled),
            (this.data.tourPlaying = !1),
            await this.data.stopTourTransition(),
            this.tourGenerator && this.engine.stopGenerator(this.tourGenerator),
            this.engine.broadcast(new d.NR()),
            this.data.getTourCurrentSnapshotIndex() !==
              this.data.getSnapshotCount() - 1 ||
              this.data.isLooping() ||
              ((this.data.tourEnded = !0), this.engine.broadcast(new d.Mt())),
            this.data.setTourState(a.Vs.Inactive))
        }
        async tourGoNext(e) {
          let t = this.data.getTourCurrentSnapshotIndex() + 1
          t >= this.data.getSnapshotCount() && (t = 0)
          const i = e ? l.n.Instant : void 0
          return this.tourGoTo(t, i)
        }
        async tourGoPrevious(e) {
          let t = this.data.getTourCurrentSnapshotIndex()
          t < 0 && (t = 0)
          let i = t - 1
          i < 0 && (i = this.data.getSnapshotCount() - 1)
          const s = e ? l.n.Instant : void 0
          return this.tourGoTo(i, s)
        }
        async tourGoTo(e, t = l.n.FadeToBlack) {
          if (!this.canChangeTourLocation())
            throw new q.z(
              'Cannot change tour location at this time, another transition is active'
            )
          if (
            this.viewmodeData.transition &&
            this.viewmodeData.transition.active
          )
            throw new q.z(
              'Cannot go to tour location during viewmode transition'
            )
          if (this.data.getTourState() !== a.Vs.Inactive)
            throw new q.z('Cannot jump to tour location while tour is active')
          try {
            this.data.setTourState(a.Vs.Active),
              await this.composeTourTransition(e, M.BZ.None, t)
          } catch (e) {
            this.log.error(e)
          } finally {
            this.data.setTourState(a.Vs.Inactive)
          }
        }
        setupAutoPlay(e) {
          const t = 1e3 * n.Xd.autoStartDelay,
            i = () => {
              let e = !0
              const i = this.cameraData.pose.onChanged(() => {
                ;(e = !1), i.cancel()
              })
              setTimeout(() => {
                e && this.startTour(), i.cancel()
              }, t)
            }
          if (t >= 0) {
            const t = e.market.tryGetData(m.pu)
            if (t && t.phase === m.nh.PLAYING) i()
            else {
              const t = (s) => {
                s.phase === m.nh.PLAYING && (i(), e.unsubscribe(w.LZ, t))
              }
              e.subscribe(w.LZ, t)
            }
          }
        }
      }
    },
    81627: (e, t, i) => {
      'use strict'
      i.r(t), i.d(t, { default: () => ToursModule })
      var s,
        n = i(3248),
        r = i(47724),
        o = i(33874),
        a = i(94329),
        h = i(75892),
        l = i(43205),
        d = i(65814),
        c = i(79956),
        u = i(88512),
        p = i(94474),
        g = i(94308),
        m = i(75256),
        w = i(23573)
      class HighlightReel extends w.T {
        constructor() {
          super(),
            (this.reel = (0, m.C)([])),
            (this.modified = new Date(0)),
            this.commit()
        }
      }
      !(function (e) {
        ;(e.INSTANT = 'instant'),
          (e.FACE_TO_BLACK = 'fade_to_black'),
          (e.INTERPOLATE = 'interpolate'),
          (e.MOVE_TO_BLACK = 'move_to_black')
      })(s || (s = {}))
      var f = i(16047),
        v = i(31278),
        T = i(52599)
      const y = new u.Z('mds-reel-element-serializer'),
        S = {
          [s.FACE_TO_BLACK]: v.n.FadeToBlack,
          [s.INSTANT]: v.n.Instant,
          [s.INTERPOLATE]: v.n.Interpolate,
          [s.MOVE_TO_BLACK]: v.n.MoveToBlack
        },
        P = {
          [f.Y.LEFT]: T.kw.Left,
          [f.Y.RIGHT]: T.kw.Right,
          [f.Y.AUTO]: T.kw.Auto
        }
      class MdsReelEntryDeserializer {
        deserialize(e) {
          if (!e || !this.validate(e))
            return (
              y.debug('Deserialized invalid highlight reel entry from MDS', e),
              null
            )
          const t = e.overrides || {},
            i = {},
            s = void 0 !== t.transitionType ? S[t.transitionType] : void 0,
            n = void 0 !== t.panDirection ? P[t.panDirection] : void 0,
            r = t.panAngle
          void 0 !== s && (i.transitionType = s),
            void 0 !== n && (i.panDirection = n),
            void 0 !== r && (i.panAngle = r)
          return { sid: e.asset.id, overrides: i }
        }
        validate(e) {
          var t
          return !!(null === (t = null == e ? void 0 : e.asset) || void 0 === t
            ? void 0
            : t.id)
        }
      }
      const D = new u.Z('mds-highlight-reel-serializer')
      class MdsHighlightReelDeserializer {
        constructor() {
          this.reelEntrySerializer = new MdsReelEntryDeserializer()
        }
        deserialize(e) {
          if (!e || !this.validate(e))
            return (
              D.debug('Deserialized invalid active reel data from MDS', e), null
            )
          const t = new HighlightReel()
          if (((t.sid = e.id), e.reel))
            for (const i of e.reel) {
              const e = this.reelEntrySerializer.deserialize(i)
              e && t.reel.push(e)
            }
          return t
        }
        validate(e) {
          return ['id'].every((t) => t in e)
        }
      }
      const b = {
          [v.n.FadeToBlack]: s.FACE_TO_BLACK,
          [v.n.Instant]: s.INSTANT,
          [v.n.Interpolate]: s.INTERPOLATE,
          [v.n.MoveToBlack]: s.MOVE_TO_BLACK
        },
        M = {
          [T.kw.Left]: f.Y.LEFT,
          [T.kw.Right]: f.Y.RIGHT,
          [T.kw.Auto]: f.Y.AUTO
        }
      class MdsReelEntrySerializer {
        serialize(e) {
          const t = { id: e.sid }
          return (
            e.overrides &&
              ((t.overrides = {}),
              void 0 !== e.overrides.transitionType &&
                (t.overrides.transitionType = b[e.overrides.transitionType]),
              void 0 !== e.overrides.panDirection &&
                (t.overrides.panDirection = M[e.overrides.panDirection]),
              void 0 !== e.overrides.panAngle &&
                (t.overrides.panAngle = e.overrides.panAngle)),
            t
          )
        }
      }
      const x = new u.Z('mds-highligh-reel-store')
      class MdsHighlightReelStore extends p.u {
        constructor() {
          super(...arguments),
            (this.deserializer = new MdsHighlightReelDeserializer()),
            (this.serializer = new MdsReelEntrySerializer()),
            (this.prefetchKey = 'data.model.activeHighlightReel')
        }
        async read(e) {
          const t = { modelId: this.getViewId() }
          return this.query(g.GetHighlightReel, t, e).then((e) => {
            var t, i
            const s =
              null ===
                (i =
                  null === (t = null == e ? void 0 : e.data) || void 0 === t
                    ? void 0
                    : t.model) || void 0 === i
                ? void 0
                : i.activeHighlightReel
            return this.deserializer.deserialize(s)
          })
        }
        async update(e) {
          const t = this.getViewId(),
            i = e.map((e) => this.serializer.serialize(e))
          return this.mutate(g.PutActiveReel, { modelId: t, elements: i }).then(
            (e) => {
              x.debug(e)
            }
          )
        }
      }
      var I = i(69941),
        R = i(38330),
        C = i(80121),
        E = i(99398),
        L = i(18630),
        F = i(31879),
        k = i(85861)
      const A = new u.Z('reel-serializers'),
        N = (e) => {
          if (!e) return null
          const t = new HighlightReel()
          return (
            e.active_reel &&
              e.active_reel.modified &&
              (t.modified = (0, F.p)(e.active_reel.modified)),
            e.active_reel &&
            e.active_reel.reel &&
            e.active_reel.reel instanceof Array
              ? (A.info('Reel has ' + e.active_reel.reel.length + ' items'),
                t.reel.replace(e.active_reel.reel))
              : A.info('No reel found'),
            t.commit(),
            t
          )
        },
        O = (e, t) => {
          let i = e.modified
          t && t.modified && (i = t.modified)
          const s = (0, k.p$)(e && e.reel ? e.reel : []),
            n = t && t.reel ? t.reel : new m.d()
          ;(0, k.TS)(s, (0, k.p$)(n))
          const r = []
          for (const e in s) {
            const t = s[e]
            if (t) {
              let e,
                i = {}
              t.overrides &&
                (void 0 !== t.overrides.panDirection &&
                  (i = Object.assign(Object.assign({}, i), {
                    panDirection: t.overrides.panDirection
                  })),
                void 0 !== t.overrides.panAngle &&
                  (i = Object.assign(Object.assign({}, i), {
                    panAngle: t.overrides.panAngle
                  })),
                void 0 !== t.overrides.transitionType &&
                  (i = Object.assign(Object.assign({}, i), {
                    transitionType: t.overrides.transitionType
                  }))),
                (e =
                  Object.keys(i).length > 0
                    ? { sid: t.sid, overrides: i }
                    : { sid: t.sid }),
                r.push(e)
            }
          }
          return { active_reel: { reel: r, modified: (0, F.U)(i) } }
        }
      var G = i(66097),
        z = i(57938),
        V = i(39729),
        U = i(26587),
        B = i(50988),
        Q = i(38420),
        _ = i(17386)
      class DeleteUnusedTourSnapshotsCommand extends _.m {
        constructor() {
          super(...arguments), (this.id = 'DELETE_UNUSED_TOUR_SNAPSHOTS')
        }
      }
      const H = new u.Z('tour-data')
      class ToursModule extends r.Y {
        constructor() {
          super(...arguments),
            (this.name = 'tours-data'),
            (this.defaultModes = [a.Ey.Panorama, a.Ey.Outdoor]),
            (this.deleteUnusedTourSnapshots = async () => {
              for (const e in this.snapshotsData.collection) {
                const t = this.snapshotsData.collection[e]
                t.category !== d.i.TOUR ||
                  this.tourData.isSnapshotInTour(t.sid) ||
                  (await this.engine.commandBinder
                    .issueCommand(new l.Ad(t.sid))
                    .catch((e) => {
                      H.debug(e),
                        H.error(
                          `Failed to delete unused tour snapshot ${t.sid}`
                        )
                    }))
              }
            }),
            (this.onUpdateSnapshots = () => {
              this.tourData.updateSnapshots(this.snapshotsData.collection)
            })
        }
        async init(e, t) {
          const { readonly: i } = e
          this.engine = t
          const s = await t.market.waitForData(o.e),
            n = this.getFilterModes(s, this.defaultModes)
          this.store = this.getStore(e)
          const r = (await this.store.read()) || new HighlightReel()
          if (
            ((this.sweepData = await t.market.waitForData(h.Z)),
            (this.snapshotsData = await t.market.waitForData(c.P)),
            (this.storage = await t.getModule(U.F)),
            (this.tourData = new I.k3(
              this.snapshotsData.collection,
              r,
              n,
              this.sweepData.getSweepList(),
              e.looping
            )),
            t.market.register(this, I.k3, this.tourData),
            !1 === i)
          ) {
            const e = this.tourData.getReel(),
              i = new z.u(e, { aggregationType: V.E.NextFrame }, t)
            i.onChanged(() =>
              this.engine.commandBinder.issueCommand(
                new B.VQ({ dataTypes: [Q.g.HIGHLIGHTS] })
              )
            ),
              this.store instanceof G.N && this.store.addMonitor(i)
          }
          this.bindings.push(
            t.commandBinder.addBinding(
              DeleteUnusedTourSnapshotsCommand,
              this.deleteUnusedTourSnapshots
            ),
            this.snapshotsData.onChanged(this.onUpdateSnapshots),
            this.storage.onSave(() => this.save(), {
              dataType: Q.g.HIGHLIGHTS
            }),
            this.storage.onRevert(() => this.revert(), {
              dataType: Q.g.HIGHLIGHTS
            })
          )
          const a = Object.keys(r.reel).length,
            l = this.tourData.getSnapshotCount()
          a !== l && H.info(a - l + ' items in snapshots, but not in reel')
        }
        getStore(e) {
          if (this.store) return this.store
          const { modelId: t, baseUrl: i, queue: s } = e,
            n = e.storageProvider || Q.Xq.JSONSTORE,
            r = !('readonly' in e) || !!e.readonly
          if ((H.info(`Loading Highlight Reel from ${n}`), n === Q.Xq.MDS))
            return new MdsHighlightReelStore({ readonly: r, baseUrl: i })
          const o = (function (e) {
            const { modelId: t, readonly: i } = e,
              s = e.baseUrl || '',
              n = e.queue,
              r = { data: null },
              o = `${s}/api/v1/jsonstore/model/highlights/${t}`
            if (i) {
              const e = new R.gh({
                queue: n,
                path: o,
                deserialize: N,
                cachedData: r
              })
              return new C.nM({ publishStores: [e] })
            }
            const a = new R.yh({
                queue: n,
                path: o,
                cachedData: r,
                deserialize: N,
                serialize: O
              }),
              h = `${s}/api/v1/jsonstore/model/workshopSession/${t}`,
              l = new L.Z(
                {
                  queue: n,
                  path: h,
                  cachedData: { data: null },
                  deserialize: E.S.sessionObjectExtract(L.j.Highlights, N),
                  serialize: O
                },
                L.j.Highlights
              )
            return new C.nM({
              publishStores: [a],
              editStore: l,
              editStoreKey: C.aw.HIGHLIGHTS
            })
          })({ modelId: t, baseUrl: i, readonly: r, queue: s })
          return new G.N(o, {
            dataType: Q.g.HIGHLIGHTS,
            readonly: r,
            engine: this.engine
          })
        }
        async save() {
          if (this.store instanceof G.N) return
          const e = this.tourData.getReel()
          await this.store.update(e.reel)
        }
        async revert() {
          if (this.store instanceof G.N) return this.store.revert()
        }
        getFilterModes(e, t) {
          const i = e.tryGetProperty('dh', 1) > 0,
            s = e.tryGetProperty(n.gx.Dollhouse, !0)
          i && s && t.push(a.Ey.Dollhouse)
          const r = e.tryGetProperty('fp', 1) > 0,
            o = e.tryGetProperty(n.gx.FloorPlan, !0)
          return r && o && t.push(a.Ey.Floorplan), t
        }
      }
    },
    86102: (e, t, i) => {
      'use strict'
      i.r(t), i.d(t, { DeletedObject: () => s.F, default: () => P })
      var s = i(76236),
        n = i(47724),
        r = i(38420),
        o = i(50988),
        a = i(26587),
        h = i(38330),
        l = i(31879)
      function d(e) {
        return {
          id: e.id,
          label: e.label,
          object_id: e.objectId,
          object_type: e.objectType,
          created: (0, l.U)(e.created),
          json_string: JSON.stringify(e.value)
        }
      }
      function c(e) {
        const t = {}
        for (const i of Object.values(e)) {
          const e = d(i)
          e && (t[i.id] = e)
        }
        return t
      }
      function u(e) {
        const t = e.id,
          i = e.label,
          n = e.object_id,
          r = e.object_type,
          o = (0, l.p)(e.created)
        let a
        try {
          a = JSON.parse(e.json_string)
        } catch (e) {}
        if (!(t && n && r && a)) return null
        return new s.F({
          id: t,
          label: i,
          objectId: n,
          objectType: r,
          created: o,
          value: a
        })
      }
      function p(e) {
        const t = {}
        for (const i in e) {
          const s = u(e[i])
          s && (t[i] = s)
        }
        return t
      }
      class TrashStore extends h.MU {
        constructor(e, t, i) {
          super({
            queue: t,
            path: `${i}/api/v1/jsonstore/model/trash/${e}`,
            batchUpdate: !0,
            deserialize: p,
            serialize: c
          })
        }
      }
      var g = i(32770),
        m = i(64781),
        w = i(10757),
        f = i(88512)
      const v = new f.Z('TrashData')
      class TrashData extends g.V {
        constructor(e) {
          super(),
            (this.trash = new m.v()),
            (this.registry = new Map()),
            e && this.add(...Object.values(e))
        }
        get(e) {
          return this.trash.get(e)
        }
        add(...e) {
          this.trash.atomic(() => {
            for (const t of e)
              t.atomic(() => {
                for (; !t.id || this.trash.has(t.id); )
                  (t.id = (0, w.O1)(11)), t.commit()
              }),
                this.trash.set(t.id, t)
          }),
            this.commit()
        }
        create(e, t) {
          const i = this.registry.get(e)
          if (!i) return void v.debug(`Unsupported type added to trash: ${e}`)
          const s = i.create(t)
          return this.add(s), s
        }
        restore(e) {
          const t = this.trash.get(e),
            i = this.registry.get(t.objectType)
          if (!i)
            throw new Error(`Can't restore unsupported type ${t.objectType}`)
          return i.restore(t)
        }
        register(e) {
          v.debug(`Registered type ${e.objectType}`)
          const { objectType: t } = e
          this.registry.has(t)
            ? v.debug(`Type ${t} already registered`)
            : this.registry.set(t, e)
        }
        unregister(e) {
          return v.debug(`Unregistered type ${e}`), this.registry.delete(e)
        }
        isSupported(e) {
          return this.registry.has(e)
        }
      }
      var T = i(93673),
        y = i(44283)
      const S = new f.Z('Trash')
      class TrashModule extends n.Y {
        constructor() {
          super(...arguments), (this.name = 'trash')
        }
        async init(e, t) {
          const { modelId: i, queue: s, baseUrl: n } = e,
            { market: o, commandBinder: h } = t
          ;(this.engine = t),
            (this.store = new TrashStore(i, s, n)),
            (this.data = new TrashData()),
            o.register(this, TrashData, this.data),
            this.engine.getModule(a.F).then((e) => {
              this.bindings.push(
                e.onPublish(async () => this.backup(), { phase: r.Q.BEFORE })
              )
            }),
            this.bindings.push(
              h.addBinding(T.B, async (e) => this.registerDeletedObject(e)),
              h.addBinding(T.p, async ({ id: e }) => this.restore(e))
            )
        }
        dispose(e) {
          super.dispose(e), e.market.unregister(this, TrashData)
        }
        async registerDeletedObject(e) {
          const { objectType: t } = e
          return (0, y.k1)(
            () => this.data.register(e),
            () => this.data.unregister(t),
            !0
          )
        }
        async backup() {
          const { commandBinder: e } = this.engine,
            t = await e.issueCommand(new o.ff()),
            i = {}
          for (const e in t)
            this.data.isSupported(e) &&
              t[e].forEach((t) => {
                const s = this.data.create(e, t)
                s && (i[s.id] = s)
              })
          if (Object.keys(i).length) return this.store.update(i)
        }
        async restore(...e) {
          const t = new Set()
          for (const i of e) {
            const e = this.data.get(i)
            S.debug(`Restoring ${e.objectType} ${e.id}`),
              Object.values(r.g).includes(null == e ? void 0 : e.objectType) &&
                t.add(e.objectType),
              this.data.restore(i)
          }
          if (t.size > 0)
            return this.engine.commandBinder.issueCommand(
              new o.VQ({ dataTypes: [...t] })
            )
        }
      }
      const P = TrashModule
    },
    15903: (e, t, i) => {
      'use strict'
      i.r(t), i.d(t, { default: () => VideoRecorderModule })
      var s = i(96909),
        n = i(88512),
        r = i(47724),
        o = i(96216),
        a = i(24930),
        h = i(91302),
        l = i(60771),
        d = i(8430)
      class FrostMage {
        constructor() {
          ;(this._dateNow = Date.now),
            (this._performanceNow = performance.now),
            (this.nowOverride = 0)
        }
        slowTime(e) {
          ;(this.fps = e),
            (this.nowOverride = Date.now()),
            (Date.now = () => this.nowOverride),
            (performance.now = () => this.nowOverride)
        }
        tick() {
          this.nowOverride += 1e3 / this.fps
        }
        resetTime() {
          ;(Date.now = this._dateNow), (performance.now = this._performanceNow)
        }
      }
      var c = i(36016),
        u = i(76701)
      const p = new n.Z('video-recorder')
      var g
      !(function (e) {
        ;(e[(e.STOPPED = 0)] = 'STOPPED'), (e[(e.RECORDING = 1)] = 'RECORDING')
      })(g || (g = {}))
      class VideoRecorderModule extends r.Y {
        constructor() {
          super(...arguments),
            (this.name = 'video-recorder-module'),
            (this.state = g.STOPPED),
            (this.frostMage = new FrostMage())
        }
        async init(e, t) {
          ;(this.settingsModule = await t.getModule(a.default)),
            (this.webglRenderer = await t.getModuleBySymbol(
              s.y.WEBGL_RENDERER
            )),
            (this.engine = t),
            this.settingsModule.registerButton(
              'Tour Recorder (Chrome Only)',
              'Download 1080p @ 60',
              () => {
                this.state === g.STOPPED && this.record(1920, 1080, 60)
              }
            ),
            this.settingsModule.registerButton(
              'Tour Recorder (Chrome Only)',
              'Download 720p @ 30',
              () => {
                this.state === g.STOPPED && this.record(1280, 720, 30)
              }
            ),
            this.settingsModule.registerButton(
              'Tour Recorder (Chrome Only)',
              'Download instagram',
              () => {
                this.state === g.STOPPED && this.record(1080, 1080, 30)
              }
            ),
            this.settingsModule.registerButton(
              'Tour Recorder (Chrome Only)',
              'Download instagram story',
              () => {
                this.state === g.STOPPED && this.record(1080, 1920, 30)
              }
            ),
            this.settingsModule.registerButton(
              'Tour Recorder (Chrome Only)',
              'Stop & download current',
              () => {
                this.state === g.RECORDING && this.stop()
              }
            )
        }
        async record(e, t, s) {
          if (this.state !== g.STOPPED)
            return void p.warn(
              "Can't start recording... we're already recording!"
            )
          p.info(
            'Starting recording of tour. Now is a good time to get a coffee :)'
          ),
            (this.state = g.RECORDING)
          const n = await Promise.all([i.e(764), i.e(524), i.e(718)]).then(
            i.bind(i, 64875)
          )
          ;(this.encoder = new n.WebMWriter({ quality: 0.95, frameRate: s })),
            this.frostMage.slowTime(s),
            await this.engine.commandBinder.issueCommand(
              new d.M({
                resizeDimensions: [
                  { property: d.P.width, setDimension: e, duration: 0 },
                  { property: d.P.height, setDimension: t, duration: 0 }
                ]
              })
            ),
            await this.engine.commandBinder.issueCommand(new o.TH())
          const r = this.engine.subscribe(h.NR, () => {
              r.cancel(), this.state === g.RECORDING && this.stop()
            }),
            a = this,
            l = a.webglRenderer.cwfRenderer.renderer.getContext().canvas
          this.engine.startGenerator(function* () {
            for (; a.state === g.RECORDING; )
              a.encoder.addFrame(l),
                yield new u.Jj(),
                a.frostMage.tick(),
                yield new u.Jj()
          })
        }
        async stop() {
          if (this.state !== g.RECORDING)
            return void p.warn(
              "Can't stop recording, we weren't recording at all"
            )
          this.frostMage.resetTime(),
            (this.state = g.STOPPED),
            await this.engine.commandBinder.issueCommand(new d.M((0, c.lb)(0))),
            p.info('Encoding tour to video...')
          const e = await this.encoder.complete()
          p.info('Tour encoded! Prompting user to download.'),
            (0, l.Hx)(e, 'tour.webm')
        }
      }
    },
    75708: (e, t, i) => {
      'use strict'
      i.r(t), i.d(t, { default: () => ee })
      var s = i(88512),
        n = i(47724),
        r = i(17490),
        o = i(7170),
        a = i(19674),
        h = i(2212),
        l = i(12216),
        d = i(77719),
        c = i(59088),
        u = i(17399),
        p = i(44019),
        g = i(33874),
        m = i(27687)
      const w = new h.Vector3(0, -100, 0),
        f = new h.Vector2(-2, -2),
        v = new h.Vector3(-1, -1, -1),
        T = new h.Vector3(1, 1, 1)
      class RaycastPointerWorld {
        constructor(e) {
          ;(this.raycaster = e),
            (this.lastHits = []),
            (this.lastRay = new h.Ray(w, new h.Vector3(0, -1, 0))),
            (this.currentRay = new h.Ray()),
            (this.origin = w),
            (this.direction = new h.Vector3()),
            (this.pointerNdc = f),
            (this.cameraCache = {
              position: new h.Vector3(),
              quaternion: new h.Quaternion(),
              camera: void 0
            }),
            (this.cast = () => {
              const e = this.currentRay
              return (
                this.lastRay.equals(e) ||
                  ((this.lastHits = this.raycaster
                    .cast(e.origin, e.direction)
                    .slice()),
                  this.lastRay.copy(e)),
                this.lastHits
              )
            }),
            (this.update3D = (e, t, i) => {
              e instanceof h.Vector3 && this.origin.copy(e),
                t instanceof h.Vector3 && this.direction.copy(t),
                (this.cameraCache.camera = i),
                this.currentRay.set(this.origin, this.direction)
            }),
            (this.updateNDCPosition = () => {
              const e = this.lastHits[0]
              if (this.cameraCache.camera && e && e.point) {
                const t = this.cameraCache.camera
                this.cameraCache.position.setFromMatrixPosition(t.matrixWorld),
                  this.cameraCache.quaternion.setFromRotationMatrix(
                    t.matrixWorld
                  )
                const i = (0, m.D_)(
                  e.point,
                  this.cameraCache.position,
                  this.cameraCache.quaternion,
                  t.projectionMatrix
                )
                i.clamp(v, T), this.pointerNdc.set(i.x, i.y)
              }
            }),
            (this.updatePointer = () => {})
        }
        get pointerRay() {
          return this.currentRay
        }
        get ndcPosition() {
          return this.updateNDCPosition(), this.pointerNdc
        }
      }
      var y = i(91466)
      class XRTrackingMessage extends y.v {}
      class XRTrackingAppliedMessage extends XRTrackingMessage {
        constructor(e) {
          super(), (this.trackedCamera = e)
        }
      }
      class XRStartPresentingMessage extends XRTrackingMessage {}
      class XRStopPresentingMessage extends XRTrackingMessage {}
      var S,
        P = i(1630),
        D = i(63432),
        b = i(84561)
      !(function (e) {
        ;(e[(e.Mono = 0)] = 'Mono'),
          (e[(e.Stereo = 1)] = 'Stereo'),
          (e[(e.SixDof = 2)] = 'SixDof'),
          (e[(e.__length = 3)] = '__length')
      })(S || (S = {}))
      const M = { controllers: Object.freeze([0, 1]), rotationDegrees: 25 }
      var x
      !(function (e) {
        ;(e[(e.touchpadX = 0)] = 'touchpadX'),
          (e[(e.touchpadY = 1)] = 'touchpadY'),
          (e[(e.thumbstickX = 2)] = 'thumbstickX'),
          (e[(e.thumbstickY = 3)] = 'thumbstickY')
      })(x || (x = {}))
      const I = { x: 0, y: 0, z: 0, w: 1 }
      class XRTrackingOverrides extends D.Y {
        constructor(e, t, i, s, n) {
          super(),
            (this.engine = e),
            (this.renderer = t),
            (this.webglScene = i),
            (this.cameraData = s),
            (this.cameraModule = n),
            (this.trackingStyle = S.Mono),
            (this.session = null),
            (this.rotations = {
              initialYawOffset: new h.Quaternion(),
              yawOffset: new h.Quaternion(),
              invYawOffset: new h.Quaternion(),
              trackingOffset: new h.Quaternion()
            }),
            (this.setTrackingStyle = (e) => {
              e < S.__length &&
                ((this.trackingStyle = e), this.resetInitialRotation())
            }),
            (this.offsetRotation = (e) => {
              this.rotations.invYawOffset.multiply(e),
                this.rotations.yawOffset
                  .copy(this.rotations.invYawOffset)
                  .invert()
            }),
            (this.onPresentStart = (e) => {
              ;(e.cameras[0].layers.mask = b.o.ALL.mask),
                (e.cameras[1].layers.mask = b.o.ALL.mask),
                (e.cameras[0].far = e.far),
                (e.cameras[1].far = e.far),
                (e.layers.mask = b.o.ALL.mask),
                this.resetInitialRotation(),
                this.broadcast(new XRStartPresentingMessage())
            }),
            (this.resetInitialRotation = () => {
              const e = this.cameraData.pose.rotation.clone()
              ;(0, a.Rq)(e, this.rotations.initialYawOffset),
                this.rotations.yawOffset.copy(this.rotations.initialYawOffset),
                this.rotations.invYawOffset
                  .copy(this.rotations.initialYawOffset)
                  .invert()
            }),
            (this.onPresentEnd = () => {
              this.broadcast(new XRStopPresentingMessage())
            }),
            (this.applyTrackingOverrides = (e, t, i) => {
              if (e.xr.isPresenting && i instanceof h.ArrayCamera) {
                e.clear()
                const t = i.cameras[0],
                  s = i.cameras[1]
                if (
                  ((this.frame = this.engine.getXrFrame()),
                  this.session ||
                    ((this.session = e.xr.getSession()),
                    this.onPresentStart(i)),
                  this.frame && this.session)
                ) {
                  this.rotations.trackingOffset
                    .copy(this.rotations.yawOffset)
                    .multiply(i.quaternion),
                    this.cameraModule.updateCameraRotation(
                      this.rotations.trackingOffset
                    )
                  const e = this.webglScene.camera.parent
                  if (e) {
                    const t = this.getReferenceSpace(this.frame, e)
                    this.updateCameras(i, this.frame, t, e),
                      this.updateControllers(this.session, this.frame, t, e)
                  }
                  switch (this.trackingStyle) {
                    case S.Mono:
                      s.matrixWorld.copy(t.matrixWorld),
                        s.matrixWorldInverse.copy(s.matrixWorld),
                        s.matrixWorldInverse.invert()
                  }
                  this.broadcast(new XRTrackingAppliedMessage(t))
                }
              } else
                this.session && ((this.session = null), this.onPresentEnd())
            }),
            (this.getReferenceSpace = (e, t) => {
              const i = this.renderer.xr.getReferenceSpace(),
                s = e.getViewerPose(i).views[0].transform.position,
                n = this.trackingStyle === S.SixDof ? I : s,
                r = new XRRigidTransform({
                  x: n.x - t.position.x,
                  y: n.y - t.position.y,
                  z: n.z - t.position.z
                }),
                o = i.getOffsetReferenceSpace(r),
                a = this.rotations.invYawOffset,
                h = this.cameraData.pose.position,
                l = new XRRigidTransform(
                  { x: h.x, y: h.y, z: h.z, w: 1 },
                  { x: a.x, y: a.y, z: a.z, w: a.w }
                )
              return o.getOffsetReferenceSpace(l)
            }),
            (this.updateCameras = (e, t, i, s) => {
              const n = t.getViewerPose(i)
              if (n) {
                const t = n.views
                for (let i = 0; i < t.length; i++) {
                  const n = t[i],
                    r = e.cameras[i]
                  r.matrix.fromArray(n.transform.matrix),
                    r.projectionMatrix.fromArray(n.projectionMatrix),
                    r.projectionMatrixInverse.copy(r.projectionMatrix),
                    r.projectionMatrixInverse.invert(),
                    r.matrixWorld.multiplyMatrices(s.matrixWorld, r.matrix),
                    r.matrixWorldInverse.copy(r.matrixWorld),
                    r.matrixWorldInverse.invert(),
                    r.matrix.decompose(r.position, r.quaternion, r.scale),
                    0 === i &&
                      (e.matrix.copy(r.matrix),
                      e.matrix.decompose(e.position, e.quaternion, e.scale),
                      e.matrixWorld.copy(r.matrixWorld),
                      e.matrixWorldInverse.copy(r.matrixWorldInverse),
                      e.projectionMatrix.copy(r.projectionMatrix),
                      e.projectionMatrixInverse.copy(r.projectionMatrixInverse))
                }
              }
            }),
            (this.updateControllers = (e, t, i, s) => {
              for (let n = 0; n < 2; n++) {
                const r = this.renderer.xr.getController(n),
                  o = this.renderer.xr.getControllerGrip(n),
                  a = e.inputSources[n]
                let h = null,
                  l = null
                a &&
                  (r &&
                    ((h = t.getPose(a.targetRaySpace, i)),
                    h &&
                      (r.matrix.fromArray(h.transform.matrix),
                      r.matrixWorld.multiplyMatrices(s.matrixWorld, r.matrix),
                      r.matrix.decompose(r.position, r.quaternion, r.scale)),
                    (r.visible = !!h)),
                  o &&
                    a.gripSpace &&
                    ((l = t.getPose(a.gripSpace, i)),
                    l &&
                      (o.matrix.fromArray(l.transform.matrix),
                      o.matrixWorld.multiplyMatrices(s.matrixWorld, o.matrix),
                      o.children.forEach((e) => {
                        e.updateMatrixWorld()
                      }),
                      o.matrix.decompose(o.position, o.quaternion, o.scale)))),
                  o && (o.visible = !!l)
              }
            }),
            (this.webglScene.scene.onBeforeRender = this.applyTrackingOverrides)
        }
      }
      var R = i(48715),
        C = i(53225),
        E = i(26589),
        L = i(23275),
        F = i(82088),
        k = i(95586),
        A = i(16101),
        N = i(75892),
        O = i(19047),
        G = i(35597),
        z = i(69927),
        V = i(66223),
        U = i(33757)
      class XRNavigationVisuals {
        constructor() {
          ;(this.active = !1),
            (this.target = new R.f(null)),
            (this.previousSweep = null),
            (this.activate = () => {
              this.active ||
                (this.updateLoopSub.renew(),
                this.selectionChangeSub.renew(),
                this.ray.toggle(!0),
                this.targetDecoration.toggle(!0),
                (this.active = !0))
            }),
            (this.deactivate = () => {
              this.active &&
                ((this.target.value = null),
                this.selectionChangeSub.cancel(),
                this.updateLoopSub.cancel(),
                this.ray.toggle(!1),
                this.targetDecoration.toggle(!1),
                (this.active = !1))
            }),
            (this.getTargetSweep = (e, t, i) => {
              let s = null
              if (t.object instanceof A.YY)
                return (s = e.getSweep(t.object.userData.sid)), s
              const n = (0, F.bG)(e, !0, t.intersection)
              return (s = n.length > 0 ? n[0].sweep : null), s
            })
        }
        get container() {
          return this._container
        }
        async init(e) {
          ;(this.engine = e),
            (this._container = new h.Group()),
            (this._container.name = 'XRNavigationVisuals'),
            (this.ray = new XRTargetRay(this.container)),
            (this.targetDecoration = new XRTargetDecoration(this.container))
          const t = await this.engine.market.waitForData(p.P)
          return (
            (this.updateLoopSub = t.onChanged(() => this.update(t))),
            this.updateLoopSub.cancel(),
            (this.selectionChangeSub = this.target.onChanged((e) => {
              null !== this.previousSweep &&
                this.engine.commandBinder.issueCommand(
                  new k.kR(this.previousSweep.id, !1, 200)
                ),
                null !== e &&
                  (this.engine.commandBinder.issueCommand(
                    new k.kR(e.id, !0, 200)
                  ),
                  this.targetDecoration.updateTargetPosition(e.floorPosition)),
                (this.previousSweep = e)
            })),
            this.selectionChangeSub.cancel(),
            this
          )
        }
        update(e) {
          const t = this.engine.market.tryGetData(N.Z),
            i = this.engine.market.tryGetData(c.M_),
            s = this.engine.market.tryGetData(G.O),
            n = this.engine.market.tryGetData(z.Y),
            r = this.engine.market.tryGetData(O.Z)
          if (!(t && i && s && r && n)) return
          if (!r.isVR()) return
          if (!s.isInside()) return
          const { hit: o, pointerDirection: a, pointerOrigin: h } = e
          if (!o) return
          const l = this.getTargetSweep(t, o, a)
          ;(this.target.value = l),
            this.ray.update(h, o.point, n.opacity.value),
            this.targetDecoration.update(i.pose.rotation, n.opacity.value)
        }
      }
      class XRTargetRay {
        constructor(e) {
          ;(this.container = e),
            (this.styles = {
              ray: {
                color: 'white',
                transparent: !0,
                opacity: 0.3,
                linewidth: 2,
                depthWrite: !1
              },
              hit: { color: 'white', transparent: !0, opacity: 0.3 },
              hitScale: 0.02
            }),
            (this.update = (e, t, i) => {
              this.ray
                .updatePositions(e, t)
                .opacity(Math.min(i, this.styles.ray.opacity)),
                this.hitMarker.position.copy(t),
                (this.hitMarker.material.opacity = Math.min(
                  i,
                  this.styles.hit.opacity
                ))
            }),
            (this.toggle = (e) => {
              e
                ? (this.container.add(...this.ray.children),
                  this.container.add(this.hitMarker))
                : (this.container.remove(...this.ray.children),
                  this.container.remove(this.hitMarker))
            })
          const { ray: t, hit: i } = this.styles,
            s = E.default.makeLineMaterial(t.color, !1, t)
          ;(this.ray = new L.c(new h.Vector3(), new h.Vector3(), s, {})),
            this.ray.updateResolution(window.innerWidth, window.innerHeight),
            (this.hitMarker = new C.E(
              new h.SphereBufferGeometry(this.styles.hitScale),
              new h.MeshBasicMaterial(i)
            )),
            (this.hitMarker.name = 'hit')
        }
      }
      class XRTargetDecoration {
        constructor(e) {
          ;(this.container = e),
            (this.styles = {
              scale: 0.46,
              animationSpeed: 1,
              plane: {
                color: 'white',
                transparent: !0,
                opacity: 0.6,
                depthWrite: !1,
                depthTest: !1,
                map: (0, V.p)(U)
              }
            }),
            (this.position = new h.Vector3()),
            (this.quaternion = new h.Quaternion()),
            (this.updateTargetPosition = (e) => {
              this.position.copy((0, a.Xv)(e, l.f.UP, 0.05))
            }),
            (this.update = (e, t) => {
              const i = (0, a.Rq)(e, this.quaternion)
              this.target.quaternion.copy(i),
                this.target.position.lerp(
                  this.position,
                  this.styles.animationSpeed
                ),
                (this.target.material.opacity = Math.min(
                  t,
                  this.styles.plane.opacity
                ))
            }),
            (this.toggle = (e) => {
              e
                ? this.container.add(this.target)
                : this.container.remove(this.target)
            })
          const t = new h.PlaneBufferGeometry(1),
            i = new h.Matrix4()
          i.makeRotationFromEuler(new h.Euler(-Math.PI / 2, 0, 0, 'XYZ')),
            t.applyMatrix4(i),
            (this.target = new C.E(
              t,
              new h.MeshBasicMaterial(this.styles.plane)
            )),
            (this.target.name = 'Destination'),
            this.target.scale.set(
              this.styles.scale,
              this.styles.scale,
              this.styles.scale
            )
        }
      }
      class XRControllerFocus {
        constructor(e) {
          ;(this.controllers = e), (this._lastInputWas = 0)
        }
        focus(e) {
          e !== this._lastInputWas &&
            (M.controllers.forEach((t) => {
              this.controllers.controller(t).grip.visible = t !== e
            }),
            (this._lastInputWas = e))
        }
      }
      var B = i(44283)
      class XRControllerMesh {
        constructor(e) {
          ;(this.renderer = e),
            (this._defaultController = 0),
            (this.controllerGroups = []),
            (this.bindings = []),
            (this.cancel = () => {
              this.bindings.forEach((e) => e.cancel()),
                (this.bindings.length = 0)
            }),
            (this.container = new h.Group()),
            (this.container.name = 'XRControllerMesh'),
            M.controllers.forEach((e) => {
              const t = this.createControllerGroup(e)
              this.controllerGroups.push(t),
                this.container.add(t.grip, t.pointer)
            }),
            this.connectControllerModel(),
            (this.container.matrixAutoUpdate = !1)
        }
        controller(e = this._defaultController) {
          return this.controllerGroups[e]
        }
        setDefault(e) {
          this._defaultController = e
        }
        async connectControllerModel() {
          const e = new (
            await Promise.all([i.e(47), i.e(356), i.e(376)]).then(
              i.bind(i, 43356)
            )
          ).XRControllerModelFactory()
          M.controllers.forEach((t) => {
            const i = this.controller(t).grip
            i.add(e.createControllerModel(i))
          })
        }
        createControllerGroup(e) {
          const t = this.renderer.xr.getController(e)
          t.name = `Controller Ray ${e}`
          const i = this.renderer.xr.getControllerGrip(e)
          ;(i.name = `Controller Grip ${e}`), (i.visible = !1)
          const s = {
              index: e,
              pointer: t,
              grip: i,
              connected: !1,
              hand: 'none'
            },
            n = (e) => {
              ;(s.hand = e.data.handedness), (s.connected = !0)
            },
            r = () => {
              ;(s.hand = 'none'), (s.connected = !1)
            }
          return (
            this.bindings.push(
              (0, B.k1)(
                () => t.addEventListener('connected', n),
                () => t.removeEventListener('connected', n)
              ),
              (0, B.k1)(
                () => t.addEventListener('disconnected', r),
                () => t.removeEventListener('disconnected', r)
              )
            ),
            s
          )
        }
      }
      const Q = new s.Z('xr-input-forwarding')
      class XRControllerPointerEventAdapter {
        constructor(e) {
          ;(this.options = e),
            (this.dispatchPointerDown = (e) => {
              this.forwardEvent('pointerdown', this.mockPointerEventInit(e))
            }),
            (this.dispatchPointerUp = (e) => {
              this.forwardEvent('pointerup', this.mockPointerEventInit(e))
            }),
            (this.target = e.forwardToElement)
        }
        dispatchPointerMove(e) {
          this.forwardEvent('pointermove', this.mockPointerEventInit(e))
        }
        mockPointerEventInit(e) {
          let t = 0,
            i = 0
          if (this.options.getPointerScreenPosition) {
            const e = this.options.getPointerScreenPosition()
            ;(t = e.x), (i = e.y)
          }
          return {
            pointerType: 'gamepad',
            pointerId: e,
            clientX: t,
            clientY: i
          }
        }
        forwardEvent(e, t) {
          let i
          try {
            ;(i = window.PointerEvent
              ? new PointerEvent(e, t)
              : new MouseEvent(e, t)),
              i && this.target.dispatchEvent(i)
          } catch (e) {
            Q.error(e)
          }
        }
      }
      class XRGamepadInput extends h.EventDispatcher {
        constructor(e, t) {
          super(),
            (this.renderer = e),
            (this.options = {
              forwardNativeXrEvents: !0,
              dispatchToControllerGroup: !1,
              axisMoveTriggerThreshold: 0.5
            }),
            (this.previousGamepad = new Map()),
            (this.forwardedEvents = [
              'selectstart',
              'select',
              'selectend',
              'squeeze',
              'squeezestart',
              'squeezeend'
            ]),
            (this.active = !1),
            (this.renew = () => {
              !this.active &&
                this.options.forwardNativeXrEvents &&
                (this.addSessionListeners(), (this.active = !0))
            }),
            (this.cancel = () => {
              this.active &&
                this.options.forwardNativeXrEvents &&
                (this.removeSessionListeners(), (this.active = !1))
            }),
            (this.updateFromGamepads = () => {
              if (!this.active) return
              const e = this.renderer.xr.getSession()
              if (e)
                for (const t of M.controllers) {
                  const i = e.inputSources[t]
                  if (!i || !i.gamepad) continue
                  const s = this.renderer.xr.getController(t),
                    n = this.previousGamepad.get(i),
                    r = {
                      buttons: i.gamepad.buttons.map((e) => e.value),
                      axes: i.gamepad.axes.slice()
                    },
                    o = { controllerIndex: t, inputSource: i, axes: r.axes }
                  n &&
                    (r.buttons.forEach((e, t) => {
                      e !== n.buttons[t] &&
                        (1 === e
                          ? this.sendGamepadEvent(
                              s,
                              Object.assign(Object.assign({}, o), {
                                type: 'buttondown',
                                value: e,
                                index: t
                              })
                            )
                          : 0 === e &&
                            this.sendGamepadEvent(
                              s,
                              Object.assign(Object.assign({}, o), {
                                type: 'buttonup',
                                value: e,
                                index: t
                              })
                            ))
                    }),
                    r.axes.forEach((e, t) => {
                      const i = n.axes[t]
                      if (e !== i) {
                        this.sendGamepadEvent(
                          s,
                          Object.assign(Object.assign({}, o), {
                            type: 'axesmove',
                            value: e,
                            index: t
                          })
                        ),
                          0 === i &&
                            this.sendGamepadEvent(
                              s,
                              Object.assign(Object.assign({}, o), {
                                type: 'axesmovestart',
                                value: e,
                                index: t
                              })
                            )
                        const n = this.options.axisMoveTriggerThreshold
                        Math.abs(i) < n &&
                          Math.abs(e) > n &&
                          this.sendGamepadEvent(
                            s,
                            Object.assign(Object.assign({}, o), {
                              type: 'axestriggered',
                              value: e,
                              index: t
                            })
                          ),
                          0 === e &&
                            this.sendGamepadEvent(
                              s,
                              Object.assign(Object.assign({}, o), {
                                type: 'axesmoveend',
                                value: e,
                                index: t
                              })
                            )
                      }
                    })),
                    this.previousGamepad.set(i, r)
                }
            }),
            (this.onGamepadEvent = (e, t) =>
              (0, B.k1)(
                () => super.addEventListener(e, t),
                () => super.removeEventListener(e, t)
              )),
            (this.onSessionEvent = (e, t) =>
              (0, B.k1)(
                () => super.addEventListener(e, t),
                () => super.removeEventListener(e, t)
              )),
            (this.sendGamepadEvent = (e, t) => {
              this.dispatchEvent(t),
                this.options.dispatchToControllerGroup && e.dispatchEvent(t)
            }),
            (this.sendSessionEvent = (e, t) => {
              this.dispatchEvent({ type: e, controllerIndex: t })
            }),
            (this.addSessionListeners = () => {
              M.controllers.forEach((e) => {
                const t = this.renderer.xr.getController(e)
                for (const i of this.forwardedEvents)
                  t.addEventListener(i, (t) => this.sendSessionEvent(t.type, e))
              })
            }),
            (this.removeSessionListeners = () => {
              M.controllers.forEach((e) => {
                const t = this.renderer.xr.getController(e)
                for (const i of this.forwardedEvents)
                  t.removeEventListener(i, (t) =>
                    this.sendSessionEvent(t.type, e)
                  )
              })
            }),
            t &&
              (this.options = Object.assign(
                Object.assign({}, this.options),
                t
              )),
            this.renew()
        }
      }
      var _ = i(7855),
        H = i(42472),
        j = i(77025),
        q = i(34369),
        Z = i(37381),
        X = i(60771)
      var W = i(3805),
        Y = i(96909)
      const $ = new s.Z('xr'),
        K = new h.Quaternion().setFromAxisAngle(
          l.f.UP,
          o.Ue * M.rotationDegrees
        ),
        J = new h.Quaternion().setFromAxisAngle(
          l.f.UP,
          o.Ue * -M.rotationDegrees
        )
      class WebXRModule extends n.Y {
        constructor() {
          super(...arguments),
            (this.name = 'webxr'),
            (this.framebufferScaledTo = 1),
            (this.framebufferScale = 0),
            (this.ray = { forward: new h.Vector3(), origin: new h.Vector3() }),
            (this.onXrPresentBegin = () => {
              const e = this.renderer.xr.getSession()
              $.info(`Session framebuffer: ${e.renderState.baseLayer}`),
                this.engine.commandBinder.issueCommand(new j.D(!0)),
                this.engine.commandBinder.issueCommand(new j.F(q.AB.HIGH)),
                this.viewmodeData.isInside() ||
                  this.engine.commandBinder.issueCommand(new W._i(W.BD.INSIDE)),
                (this.xrPointer = new RaycastPointerWorld(
                  this.raycaster.picking
                )),
                this.raycaster.setOverridePointer(this.xrPointer),
                this.xrNavVisuals.activate()
            }),
            (this.onXrPresentEnd = () => {
              const e = null !== this.settings.tryGetProperty(Z.YS, null)
              this.engine.commandBinder.issueCommand(new j.D(e)),
                this.engine.commandBinder.issueCommand(
                  new j.F(this.config.navPanoSize)
                ),
                this.xrNavVisuals.deactivate(),
                this.raycaster.setOverridePointer(null),
                this.cameraModule.updateCameraRotation(
                  (0, a.Rq)(this.cameraData.pose.rotation, new h.Quaternion())
                ),
                this.webglScene.setCameraDirty()
            }),
            (this.onXrTrackingApplied = (e) => {
              const t = this.controllerMesh.controller()
              if (t.connected) {
                const i = this.ray.forward
                    .copy(l.f.FORWARD)
                    .applyQuaternion(t.pointer.quaternion),
                  s = this.ray.origin.setFromMatrixPosition(
                    t.pointer.matrixWorld
                  )
                this.xrPointer.update3D(s, i, e.trackedCamera),
                  this.xrPointerInput.dispatchPointerMove(t.index)
              }
              this.xrGamepadInput.updateFromGamepads()
            }),
            (this.requestSession = async (e, t) => {
              if ((await (0, _.pl)()) !== _.bk.webxr) return null
              if (this.renderer.xr.isPresenting)
                return this.renderer.xr.getSession()
              if (H.Z.apiExists()) {
                const i = await navigator.xr.requestSession(e, {
                    optionalFeatures: t
                  }),
                  s = XRWebGLLayer.getNativeFramebufferScaleFactor(i)
                return (
                  (this.framebufferScaledTo =
                    this.framebufferScale * (s - 1) + 1),
                  $.info(
                    'Scaling framebuffer by:',
                    this.framebufferScaledTo,
                    'native size:',
                    s,
                    ' * factor:',
                    this.framebufferScale
                  ),
                  0 !== this.framebufferScale &&
                    this.renderer.xr.setFramebufferScaleFactor(
                      this.framebufferScaledTo
                    ),
                  this.renderer.xr.setSession(i),
                  i
                )
              }
              return null
            })
        }
        async init(e, t) {
          ;(this.config = e), (this.engine = t)
          const i = await t.getModuleBySymbol(Y.y.WEBGL_RENDERER)
          ;(this.renderer = i.threeRenderer),
            (this.webglScene = i.getScene()),
            (this.settings = await t.market.waitForData(g.e)),
            this.bindings.push(
              t.commandBinder.addBinding(P.j, (e) =>
                this.requestSession(e.type, e.features)
              )
            )
          if ((await (0, _.pl)()) !== _.bk.webxr) return
          ;([this.canvasModule, this.cameraModule, this.raycaster] =
            await Promise.all([
              t.getModuleBySymbol(Y.y.CANVAS),
              t.getModule(d.default),
              t.getModule(u.default)
            ])),
            ([this.cameraData, this.raycasterData, this.viewmodeData] =
              await Promise.all([
                t.market.waitForData(c.M_),
                t.market.waitForData(p.P),
                t.market.waitForData(G.O)
              ])),
            this.renderer.xr.setReferenceSpaceType('local'),
            (this.framebufferScale =
              this.config.framebufferScaling ||
              (function (e) {
                const t = (0, X.tq)()
                return !t ||
                  (t &&
                    (function (e) {
                      return /Adreno \(TM\) (540|[6-9]\d\d)/.test(e.renderer)
                    })(e))
                  ? 1
                  : 0
              })(i.gpuInfo))
          const s = new XRTrackingOverrides(
            t,
            this.renderer,
            this.webglScene,
            this.cameraData,
            this.cameraModule
          )
          s.setTrackingStyle(e.tracking),
            this.bindings.push(
              s.subscribe(XRStartPresentingMessage, this.onXrPresentBegin),
              s.subscribe(XRStopPresentingMessage, this.onXrPresentEnd),
              s.subscribe(XRTrackingAppliedMessage, this.onXrTrackingApplied)
            ),
            (this.controllerMesh = new XRControllerMesh(this.renderer)),
            this.webglScene.add(this.controllerMesh.container)
          const n = new XRControllerFocus(this.controllerMesh),
            o = e.enableEventPositions
              ? () => this.raycasterData.pointerScreenPosition
              : void 0
          ;(this.xrPointerInput = new XRControllerPointerEventAdapter({
            forwardToElement: this.canvasModule.element,
            getPointerScreenPosition: o
          })),
            (this.xrGamepadInput = new XRGamepadInput(this.renderer))
          const a = new r.V(
            this.xrGamepadInput.onGamepadEvent('axestriggered', (e) => {
              if (e.index === x.thumbstickX || e.index === x.touchpadX) {
                $.debug(
                  `${e.inputSource.handedness} ${
                    x[e.index]
                  } axis.value over threshold, do the rotate!`
                )
                Math.sign(e.value) > 0
                  ? s.offsetRotation(K)
                  : s.offsetRotation(J)
              }
              n.focus(e.controllerIndex),
                this.controllerMesh.setDefault(e.controllerIndex)
            }),
            this.xrGamepadInput.onSessionEvent('selectstart', (e) => {
              this.xrPointerInput.dispatchPointerDown(e.controllerIndex),
                n.focus(e.controllerIndex),
                this.controllerMesh.setDefault(e.controllerIndex)
            }),
            this.xrGamepadInput.onSessionEvent('selectend', (e) => {
              this.xrPointerInput.dispatchPointerUp(e.controllerIndex),
                n.focus(e.controllerIndex),
                this.controllerMesh.setDefault(e.controllerIndex)
            }),
            this.xrGamepadInput.onSessionEvent('squeezestart', (e) => {
              n.focus(e.controllerIndex),
                this.controllerMesh.setDefault(e.controllerIndex)
            })
          )
          this.bindings.push(a, this.xrGamepadInput),
            (this.xrNavVisuals = new XRNavigationVisuals()),
            this.xrNavVisuals.init(t),
            this.webglScene.add(this.xrNavVisuals.container)
        }
      }
      const ee = WebXRModule
    },
    94308: (e) => {
      var t = {
        kind: 'Document',
        definitions: [
          {
            kind: 'OperationDefinition',
            operation: 'query',
            name: { kind: 'Name', value: 'GetHighlightReel' },
            variableDefinitions: [
              {
                kind: 'VariableDefinition',
                variable: {
                  kind: 'Variable',
                  name: { kind: 'Name', value: 'modelId' }
                },
                type: {
                  kind: 'NonNullType',
                  type: {
                    kind: 'NamedType',
                    name: { kind: 'Name', value: 'ID' }
                  }
                },
                directives: []
              }
            ],
            directives: [],
            selectionSet: {
              kind: 'SelectionSet',
              selections: [
                {
                  kind: 'Field',
                  name: { kind: 'Name', value: 'model' },
                  arguments: [
                    {
                      kind: 'Argument',
                      name: { kind: 'Name', value: 'id' },
                      value: {
                        kind: 'Variable',
                        name: { kind: 'Name', value: 'modelId' }
                      }
                    }
                  ],
                  directives: [],
                  selectionSet: {
                    kind: 'SelectionSet',
                    selections: [
                      {
                        kind: 'Field',
                        name: { kind: 'Name', value: 'id' },
                        arguments: [],
                        directives: []
                      },
                      {
                        kind: 'Field',
                        name: { kind: 'Name', value: 'activeHighlightReel' },
                        arguments: [],
                        directives: [],
                        selectionSet: {
                          kind: 'SelectionSet',
                          selections: [
                            {
                              kind: 'FragmentSpread',
                              name: {
                                kind: 'Name',
                                value: 'HighlightReelDetails'
                              },
                              directives: []
                            }
                          ]
                        }
                      }
                    ]
                  }
                }
              ]
            }
          },
          {
            kind: 'OperationDefinition',
            operation: 'mutation',
            name: { kind: 'Name', value: 'PutActiveReel' },
            variableDefinitions: [
              {
                kind: 'VariableDefinition',
                variable: {
                  kind: 'Variable',
                  name: { kind: 'Name', value: 'modelId' }
                },
                type: {
                  kind: 'NonNullType',
                  type: {
                    kind: 'NamedType',
                    name: { kind: 'Name', value: 'ID' }
                  }
                },
                directives: []
              },
              {
                kind: 'VariableDefinition',
                variable: {
                  kind: 'Variable',
                  name: { kind: 'Name', value: 'elements' }
                },
                type: {
                  kind: 'ListType',
                  type: {
                    kind: 'NonNullType',
                    type: {
                      kind: 'NamedType',
                      name: { kind: 'Name', value: 'ReelElementInput' }
                    }
                  }
                },
                directives: []
              }
            ],
            directives: [],
            selectionSet: {
              kind: 'SelectionSet',
              selections: [
                {
                  kind: 'Field',
                  name: { kind: 'Name', value: 'putActiveReel' },
                  arguments: [
                    {
                      kind: 'Argument',
                      name: { kind: 'Name', value: 'modelId' },
                      value: {
                        kind: 'Variable',
                        name: { kind: 'Name', value: 'modelId' }
                      }
                    },
                    {
                      kind: 'Argument',
                      name: { kind: 'Name', value: 'elements' },
                      value: {
                        kind: 'Variable',
                        name: { kind: 'Name', value: 'elements' }
                      }
                    }
                  ],
                  directives: [],
                  selectionSet: {
                    kind: 'SelectionSet',
                    selections: [
                      {
                        kind: 'Field',
                        name: { kind: 'Name', value: 'id' },
                        arguments: [],
                        directives: []
                      }
                    ]
                  }
                }
              ]
            }
          },
          {
            kind: 'FragmentDefinition',
            name: { kind: 'Name', value: 'HighlightReelDetails' },
            typeCondition: {
              kind: 'NamedType',
              name: { kind: 'Name', value: 'HighlightReel' }
            },
            directives: [],
            selectionSet: {
              kind: 'SelectionSet',
              selections: [
                {
                  kind: 'Field',
                  name: { kind: 'Name', value: 'id' },
                  arguments: [],
                  directives: []
                },
                {
                  kind: 'Field',
                  name: { kind: 'Name', value: 'label' },
                  arguments: [],
                  directives: []
                },
                {
                  kind: 'Field',
                  name: { kind: 'Name', value: 'reel' },
                  arguments: [],
                  directives: [],
                  selectionSet: {
                    kind: 'SelectionSet',
                    selections: [
                      {
                        kind: 'Field',
                        name: { kind: 'Name', value: 'overrides' },
                        arguments: [],
                        directives: [],
                        selectionSet: {
                          kind: 'SelectionSet',
                          selections: [
                            {
                              kind: 'Field',
                              name: { kind: 'Name', value: 'transitionType' },
                              arguments: [],
                              directives: []
                            },
                            {
                              kind: 'Field',
                              name: { kind: 'Name', value: 'panDirection' },
                              arguments: [],
                              directives: []
                            },
                            {
                              kind: 'Field',
                              name: { kind: 'Name', value: 'panAngle' },
                              arguments: [],
                              directives: []
                            }
                          ]
                        }
                      },
                      {
                        kind: 'Field',
                        name: { kind: 'Name', value: 'asset' },
                        arguments: [],
                        directives: [],
                        selectionSet: {
                          kind: 'SelectionSet',
                          selections: [
                            {
                              kind: 'InlineFragment',
                              typeCondition: {
                                kind: 'NamedType',
                                name: { kind: 'Name', value: 'Photo' }
                              },
                              directives: [],
                              selectionSet: {
                                kind: 'SelectionSet',
                                selections: [
                                  {
                                    kind: 'Field',
                                    name: { kind: 'Name', value: 'id' },
                                    arguments: [],
                                    directives: []
                                  }
                                ]
                              }
                            }
                          ]
                        }
                      }
                    ]
                  }
                }
              ]
            }
          }
        ],
        loc: { start: 0, end: 496 }
      }
      t.loc.source = {
        body: 'query GetHighlightReel($modelId: ID!) {\n  model(id: $modelId) {\n    id\n    activeHighlightReel {\n      ...HighlightReelDetails\n    }\n  }\n}\n\nmutation PutActiveReel($modelId: ID!, $elements: [ReelElementInput!]) {\n  putActiveReel(modelId: $modelId, elements: $elements) {\n    id\n  }\n}\n\nfragment HighlightReelDetails on HighlightReel {\n  id\n  label\n  reel {\n    overrides {\n      transitionType\n      panDirection\n      panAngle\n    }\n    asset {\n      ... on Photo {\n        id\n      }\n    }\n  }\n}\n',
        name: 'GraphQL request',
        locationOffset: { line: 1, column: 1 }
      }
      function i(e, t) {
        if ('FragmentSpread' === e.kind) t.add(e.name.value)
        else if ('VariableDefinition' === e.kind) {
          var s = e.type
          'NamedType' === s.kind && t.add(s.name.value)
        }
        e.selectionSet &&
          e.selectionSet.selections.forEach(function (e) {
            i(e, t)
          }),
          e.variableDefinitions &&
            e.variableDefinitions.forEach(function (e) {
              i(e, t)
            }),
          e.definitions &&
            e.definitions.forEach(function (e) {
              i(e, t)
            })
      }
      var s = {}
      function n(e, t) {
        for (var i = 0; i < e.definitions.length; i++) {
          var s = e.definitions[i]
          if (s.name && s.name.value == t) return s
        }
      }
      function r(e, t) {
        var i = { kind: e.kind, definitions: [n(e, t)] }
        e.hasOwnProperty('loc') && (i.loc = e.loc)
        var r = s[t] || new Set(),
          o = new Set(),
          a = new Set()
        for (
          r.forEach(function (e) {
            a.add(e)
          });
          a.size > 0;

        ) {
          var h = a
          ;(a = new Set()),
            h.forEach(function (e) {
              o.has(e) ||
                (o.add(e),
                (s[e] || new Set()).forEach(function (e) {
                  a.add(e)
                }))
            })
        }
        return (
          o.forEach(function (t) {
            var s = n(e, t)
            s && i.definitions.push(s)
          }),
          i
        )
      }
      t.definitions.forEach(function (e) {
        if (e.name) {
          var t = new Set()
          i(e, t), (s[e.name.value] = t)
        }
      }),
        (e.exports = t),
        (e.exports.GetHighlightReel = r(t, 'GetHighlightReel')),
        (e.exports.PutActiveReel = r(t, 'PutActiveReel')),
        (e.exports.HighlightReelDetails = r(t, 'HighlightReelDetails'))
    },
    80639: (e) => {
      var t = {
        kind: 'Document',
        definitions: [
          {
            kind: 'OperationDefinition',
            operation: 'query',
            name: { kind: 'Name', value: 'GetScans' },
            variableDefinitions: [
              {
                kind: 'VariableDefinition',
                variable: {
                  kind: 'Variable',
                  name: { kind: 'Name', value: 'modelId' }
                },
                type: {
                  kind: 'NonNullType',
                  type: {
                    kind: 'NamedType',
                    name: { kind: 'Name', value: 'ID' }
                  }
                },
                directives: []
              }
            ],
            directives: [],
            selectionSet: {
              kind: 'SelectionSet',
              selections: [
                {
                  kind: 'Field',
                  name: { kind: 'Name', value: 'model' },
                  arguments: [
                    {
                      kind: 'Argument',
                      name: { kind: 'Name', value: 'id' },
                      value: {
                        kind: 'Variable',
                        name: { kind: 'Name', value: 'modelId' }
                      }
                    }
                  ],
                  directives: [],
                  selectionSet: {
                    kind: 'SelectionSet',
                    selections: [
                      {
                        kind: 'Field',
                        name: { kind: 'Name', value: 'id' },
                        arguments: [],
                        directives: []
                      },
                      {
                        kind: 'Field',
                        name: { kind: 'Name', value: 'assets' },
                        arguments: [],
                        directives: [],
                        selectionSet: {
                          kind: 'SelectionSet',
                          selections: [
                            {
                              kind: 'Field',
                              name: { kind: 'Name', value: 'scans' },
                              arguments: [],
                              directives: [],
                              selectionSet: {
                                kind: 'SelectionSet',
                                selections: [
                                  {
                                    kind: 'FragmentSpread',
                                    name: {
                                      kind: 'Name',
                                      value: 'ScanDetails'
                                    },
                                    directives: []
                                  }
                                ]
                              }
                            }
                          ]
                        }
                      }
                    ]
                  }
                }
              ]
            }
          },
          {
            kind: 'FragmentDefinition',
            name: { kind: 'Name', value: 'ScanDetails' },
            typeCondition: {
              kind: 'NamedType',
              name: { kind: 'Name', value: 'Scan' }
            },
            directives: [],
            selectionSet: {
              kind: 'SelectionSet',
              selections: [
                {
                  kind: 'Field',
                  name: { kind: 'Name', value: 'id' },
                  arguments: [],
                  directives: []
                },
                {
                  kind: 'Field',
                  name: { kind: 'Name', value: 'index' },
                  arguments: [],
                  directives: []
                },
                {
                  kind: 'Field',
                  name: { kind: 'Name', value: 'name' },
                  arguments: [],
                  directives: []
                },
                {
                  kind: 'Field',
                  name: { kind: 'Name', value: 'created' },
                  arguments: [],
                  directives: []
                },
                {
                  kind: 'Field',
                  name: { kind: 'Name', value: 'alignment' },
                  arguments: [],
                  directives: []
                },
                {
                  kind: 'Field',
                  name: { kind: 'Name', value: 'options' },
                  arguments: [],
                  directives: []
                },
                {
                  kind: 'Field',
                  name: { kind: 'Name', value: 'url' },
                  arguments: [],
                  directives: []
                },
                {
                  kind: 'Field',
                  name: { kind: 'Name', value: 'timeOfDay' },
                  arguments: [],
                  directives: []
                },
                {
                  kind: 'Field',
                  name: { kind: 'Name', value: 'anchor' },
                  arguments: [],
                  directives: [],
                  selectionSet: {
                    kind: 'SelectionSet',
                    selections: [
                      {
                        kind: 'Field',
                        name: { kind: 'Name', value: 'id' },
                        arguments: [],
                        directives: []
                      }
                    ]
                  }
                },
                {
                  kind: 'Field',
                  name: { kind: 'Name', value: 'camera' },
                  arguments: [],
                  directives: [],
                  selectionSet: {
                    kind: 'SelectionSet',
                    selections: [
                      {
                        kind: 'Field',
                        name: { kind: 'Name', value: 'id' },
                        arguments: [],
                        directives: []
                      },
                      {
                        kind: 'Field',
                        name: { kind: 'Name', value: 'name' },
                        arguments: [],
                        directives: []
                      },
                      {
                        kind: 'Field',
                        name: { kind: 'Name', value: 'vendor' },
                        arguments: [],
                        directives: []
                      },
                      {
                        kind: 'Field',
                        name: { kind: 'Name', value: 'model' },
                        arguments: [],
                        directives: []
                      },
                      {
                        kind: 'Field',
                        name: { kind: 'Name', value: 'captureMode' },
                        arguments: [],
                        directives: []
                      },
                      {
                        kind: 'Field',
                        name: { kind: 'Name', value: 'depthCameraType' },
                        arguments: [],
                        directives: []
                      },
                      {
                        kind: 'Field',
                        name: { kind: 'Name', value: 'cameraTypes' },
                        arguments: [],
                        directives: []
                      },
                      {
                        kind: 'Field',
                        name: { kind: 'Name', value: 'sensorSerialNumbers' },
                        arguments: [],
                        directives: []
                      },
                      {
                        kind: 'Field',
                        name: { kind: 'Name', value: 'serialNumber' },
                        arguments: [],
                        directives: []
                      },
                      {
                        kind: 'Field',
                        name: {
                          kind: 'Name',
                          value: 'mountCalibrationVersion'
                        },
                        arguments: [],
                        directives: []
                      },
                      {
                        kind: 'Field',
                        name: { kind: 'Name', value: 'softwareVersion' },
                        arguments: [],
                        directives: []
                      }
                    ]
                  }
                }
              ]
            }
          }
        ],
        loc: { start: 0, end: 452 }
      }
      t.loc.source = {
        body: 'query GetScans($modelId: ID!) {\n  model(id: $modelId) {\n    id\n    assets {\n      scans {\n        ...ScanDetails\n      }\n    }\n  }\n}\n\nfragment ScanDetails on Scan {\n  id\n  index\n  name\n  created\n  alignment\n  options\n  url\n  timeOfDay\n  anchor {\n    id\n  }\n  camera {\n    id\n    name\n    vendor\n    model\n    captureMode\n    depthCameraType\n    cameraTypes\n    sensorSerialNumbers\n    serialNumber\n    mountCalibrationVersion\n    softwareVersion\n  }\n}\n',
        name: 'GraphQL request',
        locationOffset: { line: 1, column: 1 }
      }
      function i(e, t) {
        if ('FragmentSpread' === e.kind) t.add(e.name.value)
        else if ('VariableDefinition' === e.kind) {
          var s = e.type
          'NamedType' === s.kind && t.add(s.name.value)
        }
        e.selectionSet &&
          e.selectionSet.selections.forEach(function (e) {
            i(e, t)
          }),
          e.variableDefinitions &&
            e.variableDefinitions.forEach(function (e) {
              i(e, t)
            }),
          e.definitions &&
            e.definitions.forEach(function (e) {
              i(e, t)
            })
      }
      var s = {}
      function n(e, t) {
        for (var i = 0; i < e.definitions.length; i++) {
          var s = e.definitions[i]
          if (s.name && s.name.value == t) return s
        }
      }
      function r(e, t) {
        var i = { kind: e.kind, definitions: [n(e, t)] }
        e.hasOwnProperty('loc') && (i.loc = e.loc)
        var r = s[t] || new Set(),
          o = new Set(),
          a = new Set()
        for (
          r.forEach(function (e) {
            a.add(e)
          });
          a.size > 0;

        ) {
          var h = a
          ;(a = new Set()),
            h.forEach(function (e) {
              o.has(e) ||
                (o.add(e),
                (s[e] || new Set()).forEach(function (e) {
                  a.add(e)
                }))
            })
        }
        return (
          o.forEach(function (t) {
            var s = n(e, t)
            s && i.definitions.push(s)
          }),
          i
        )
      }
      t.definitions.forEach(function (e) {
        if (e.name) {
          var t = new Set()
          i(e, t), (s[e.name.value] = t)
        }
      }),
        (e.exports = t),
        (e.exports.GetScans = r(t, 'GetScans')),
        (e.exports.ScanDetails = r(t, 'ScanDetails'))
    }
  }
])
